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

LCOV - code coverage report
Current view: top level - Zend - zend_opcode.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 340 404 84.2 %
Date: 2016-08-24 Functions: 18 24 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2016 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             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include <stdio.h>
      24             : 
      25             : #include "zend.h"
      26             : #include "zend_alloc.h"
      27             : #include "zend_compile.h"
      28             : #include "zend_extensions.h"
      29             : #include "zend_API.h"
      30             : 
      31             : #include "zend_vm.h"
      32             : 
      33           0 : static void zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array)
      34             : {
      35           0 :         if (extension->op_array_ctor) {
      36           0 :                 extension->op_array_ctor(op_array);
      37             :         }
      38           0 : }
      39             : 
      40           0 : static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend_op_array *op_array)
      41             : {
      42           0 :         if (extension->op_array_dtor) {
      43           0 :                 extension->op_array_dtor(op_array);
      44             :         }
      45           0 : }
      46             : 
      47       83421 : static void op_array_alloc_ops(zend_op_array *op_array, uint32_t size)
      48             : {
      49       83421 :         op_array->opcodes = erealloc(op_array->opcodes, size * sizeof(zend_op));
      50       83421 : }
      51             : 
      52       74403 : void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size)
      53             : {
      54       74403 :         op_array->type = type;
      55       74403 :         op_array->arg_flags[0] = 0;
      56       74403 :         op_array->arg_flags[1] = 0;
      57       74403 :         op_array->arg_flags[2] = 0;
      58             : 
      59       74403 :         op_array->refcount = (uint32_t *) emalloc(sizeof(uint32_t));
      60       74403 :         *op_array->refcount = 1;
      61       74403 :         op_array->last = 0;
      62       74403 :         op_array->opcodes = NULL;
      63       74403 :         op_array_alloc_ops(op_array, initial_ops_size);
      64             : 
      65       74403 :         op_array->last_var = 0;
      66       74403 :         op_array->vars = NULL;
      67             : 
      68       74403 :         op_array->T = 0;
      69             : 
      70       74403 :         op_array->function_name = NULL;
      71       74403 :         op_array->filename = zend_get_compiled_filename();
      72       74403 :         op_array->doc_comment = NULL;
      73             : 
      74       74403 :         op_array->arg_info = NULL;
      75       74403 :         op_array->num_args = 0;
      76       74403 :         op_array->required_num_args = 0;
      77             : 
      78       74403 :         op_array->scope = NULL;
      79       74403 :         op_array->prototype = NULL;
      80             : 
      81       74403 :         op_array->live_range = NULL;
      82       74403 :         op_array->try_catch_array = NULL;
      83       74403 :         op_array->last_live_range = 0;
      84             : 
      85       74403 :         op_array->static_variables = NULL;
      86       74403 :         op_array->last_try_catch = 0;
      87             : 
      88       74403 :         op_array->fn_flags = 0;
      89             : 
      90       74403 :         op_array->early_binding = -1;
      91             : 
      92       74403 :         op_array->last_literal = 0;
      93       74403 :         op_array->literals = NULL;
      94             : 
      95       74403 :         op_array->run_time_cache = NULL;
      96       74403 :         op_array->cache_size = 0;
      97             : 
      98       74403 :         memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
      99             : 
     100       74403 :         if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR) {
     101           0 :                 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array);
     102             :         }
     103       74403 : }
     104             : 
     105           4 : ZEND_API void destroy_zend_function(zend_function *function)
     106             : {
     107           4 :         if (function->type == ZEND_USER_FUNCTION) {
     108           4 :                 destroy_op_array(&function->op_array);
     109             :         } else {
     110             :                 ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
     111             :                 ZEND_ASSERT(function->common.function_name);
     112           0 :                 zend_string_release(function->common.function_name);
     113             :         }
     114           4 : }
     115             : 
     116   121808432 : ZEND_API void zend_function_dtor(zval *zv)
     117             : {
     118   121808432 :         zend_function *function = Z_PTR_P(zv);
     119             : 
     120   121808432 :         if (function->type == ZEND_USER_FUNCTION) {
     121             :                 ZEND_ASSERT(function->common.function_name);
     122       60891 :                 destroy_op_array(&function->op_array);
     123             :                 /* op_arrays are allocated on arena, so we don't have to free them */
     124             :         } else {
     125             :                 ZEND_ASSERT(function->type == ZEND_INTERNAL_FUNCTION);
     126             :                 ZEND_ASSERT(function->common.function_name);
     127   121747541 :                 zend_string_release(function->common.function_name);
     128   121747541 :                 if (!(function->common.fn_flags & ZEND_ACC_ARENA_ALLOCATED)) {
     129   121699308 :                         pefree(function, 1);
     130             :                 }
     131             :         }
     132   121808432 : }
     133             : 
     134       35674 : ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array)
     135             : {
     136       37973 :         if (op_array->static_variables &&
     137        2299 :             !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
     138        2298 :                 zend_hash_clean(op_array->static_variables);
     139             :         }
     140       35674 : }
     141             : 
     142        9924 : ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce)
     143             : {
     144             :         /* Clean all parts that can contain run-time data */
     145             :         /* Note that only run-time accessed data need to be cleaned up, pre-defined data can
     146             :            not contain objects and thus are not probelmatic */
     147        9924 :         if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
     148             :                 zend_function *func;
     149             : 
     150       23987 :                 ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
     151       11191 :                         if (func->type == ZEND_USER_FUNCTION) {
     152       11166 :                                 zend_cleanup_op_array_data((zend_op_array *) func);
     153             :                         }
     154             :                 } ZEND_HASH_FOREACH_END();
     155             :         }
     156        9924 :         if (ce->static_members_table) {
     157         358 :                 zval *static_members = ce->static_members_table;
     158         358 :                 zval *p = static_members;
     159         358 :                 zval *end = p + ce->default_static_members_count;
     160             : 
     161             : 
     162         358 :                 ce->default_static_members_count = 0;
     163         358 :                 ce->default_static_members_table = ce->static_members_table = NULL;
     164        1364 :                 while (p != end) {
     165             :                         i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
     166         648 :                         p++;
     167             :                 }
     168         356 :                 efree(static_members);
     169             :         }
     170        9922 : }
     171             : 
     172           0 : ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
     173             : {
     174           0 :         if (CE_STATIC_MEMBERS(ce)) {
     175           0 :                 zval *static_members = CE_STATIC_MEMBERS(ce);
     176           0 :                 zval *p = static_members;
     177           0 :                 zval *end = p + ce->default_static_members_count;
     178             : 
     179             : #ifdef ZTS
     180             :                 CG(static_members_table)[(zend_intptr_t)(ce->static_members_table)] = NULL;
     181             : #else
     182           0 :                 ce->static_members_table = NULL;
     183             : #endif
     184           0 :                 ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
     185           0 :                 while (p != end) {
     186             :                         i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
     187           0 :                         p++;
     188             :                 }
     189           0 :                 efree(static_members);
     190             :         }
     191           0 : }
     192             : 
     193        8119 : void _destroy_zend_class_traits_info(zend_class_entry *ce)
     194             : {
     195        8119 :         if (ce->num_traits > 0 && ce->traits) {
     196         189 :                 efree(ce->traits);
     197             :         }
     198             : 
     199        8119 :         if (ce->trait_aliases) {
     200          48 :                 size_t i = 0;
     201         169 :                 while (ce->trait_aliases[i]) {
     202          73 :                         if (ce->trait_aliases[i]->trait_method) {
     203          73 :                                 if (ce->trait_aliases[i]->trait_method->method_name) {
     204          73 :                                         zend_string_release(ce->trait_aliases[i]->trait_method->method_name);
     205             :                                 }
     206          73 :                                 if (ce->trait_aliases[i]->trait_method->class_name) {
     207          31 :                                         zend_string_release(ce->trait_aliases[i]->trait_method->class_name);
     208             :                                 }
     209          73 :                                 efree(ce->trait_aliases[i]->trait_method);
     210             :                         }
     211             : 
     212          73 :                         if (ce->trait_aliases[i]->alias) {
     213          62 :                                 zend_string_release(ce->trait_aliases[i]->alias);
     214             :                         }
     215             : 
     216          73 :                         efree(ce->trait_aliases[i]);
     217          73 :                         i++;
     218             :                 }
     219             : 
     220          48 :                 efree(ce->trait_aliases);
     221             :         }
     222             : 
     223        8119 :         if (ce->trait_precedences) {
     224          11 :                 size_t i = 0;
     225             : 
     226          37 :                 while (ce->trait_precedences[i]) {
     227          15 :                         zend_string_release(ce->trait_precedences[i]->trait_method->method_name);
     228          15 :                         zend_string_release(ce->trait_precedences[i]->trait_method->class_name);
     229          15 :                         efree(ce->trait_precedences[i]->trait_method);
     230             : 
     231          15 :                         if (ce->trait_precedences[i]->exclude_from_classes) {
     232           4 :                                 size_t j = 0;
     233           4 :                                 zend_trait_precedence *cur_precedence = ce->trait_precedences[i];
     234          12 :                                 while (cur_precedence->exclude_from_classes[j].class_name) {
     235           4 :                                         zend_string_release(cur_precedence->exclude_from_classes[j].class_name);
     236           4 :                                         j++;
     237             :                                 }
     238           4 :                                 efree(ce->trait_precedences[i]->exclude_from_classes);
     239             :                         }
     240          15 :                         efree(ce->trait_precedences[i]);
     241          15 :                         i++;
     242             :                 }
     243          11 :                 efree(ce->trait_precedences);
     244             :         }
     245        8119 : }
     246             : 
     247     4560076 : ZEND_API void destroy_zend_class(zval *zv)
     248             : {
     249             :         zend_property_info *prop_info;
     250     4560076 :         zend_class_entry *ce = Z_PTR_P(zv);
     251             : 
     252     4560076 :         if (--ce->refcount > 0) {
     253        7965 :                 return;
     254             :         }
     255     4552111 :         switch (ce->type) {
     256             :                 case ZEND_USER_CLASS:
     257        8119 :                         if (ce->default_properties_table) {
     258        2408 :                                 zval *p = ce->default_properties_table;
     259        2408 :                                 zval *end = p + ce->default_properties_count;
     260             : 
     261       25797 :                                 while (p != end) {
     262             :                                         i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
     263       20981 :                                         p++;
     264             :                                 }
     265        2408 :                                 efree(ce->default_properties_table);
     266             :                         }
     267        8119 :                         if (ce->default_static_members_table) {
     268           0 :                                 zval *p = ce->default_static_members_table;
     269           0 :                                 zval *end = p + ce->default_static_members_count;
     270             : 
     271           0 :                                 while (p != end) {
     272             :                                         i_zval_ptr_dtor(p ZEND_FILE_LINE_CC);
     273           0 :                                         p++;
     274             :                                 }
     275           0 :                                 efree(ce->default_static_members_table);
     276             :                         }
     277       50993 :                         ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
     278       21437 :                                 if (prop_info->ce == ce || (prop_info->flags & ZEND_ACC_SHADOW)) {
     279        3037 :                                         zend_string_release(prop_info->name);
     280        3037 :                                         if (prop_info->doc_comment) {
     281          57 :                                                 zend_string_release(prop_info->doc_comment);
     282             :                                         }
     283             :                                 }
     284             :                         } ZEND_HASH_FOREACH_END();
     285        8119 :                         zend_hash_destroy(&ce->properties_info);
     286        8119 :                         zend_string_release(ce->name);
     287        8119 :                         zend_hash_destroy(&ce->function_table);
     288        8119 :                         if (zend_hash_num_elements(&ce->constants_table)) {
     289             :                                 zend_class_constant *c;
     290             : 
     291       14871 :                                 ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
     292        7199 :                                         if (c->ce == ce) {
     293         365 :                                                 zval_ptr_dtor(&c->value);
     294         365 :                                                 if (c->doc_comment) {
     295           8 :                                                         zend_string_release(c->doc_comment);
     296             :                                                 }
     297             :                                         }
     298             :                                 } ZEND_HASH_FOREACH_END();
     299         473 :                                 zend_hash_destroy(&ce->constants_table);
     300             :                         }
     301        8119 :                         if (ce->num_interfaces > 0 && ce->interfaces) {
     302         751 :                                 efree(ce->interfaces);
     303             :                         }
     304        8119 :                         if (ce->info.user.doc_comment) {
     305          73 :                                 zend_string_release(ce->info.user.doc_comment);
     306             :                         }
     307             : 
     308        8119 :                         _destroy_zend_class_traits_info(ce);
     309             : 
     310        8119 :                         break;
     311             :                 case ZEND_INTERNAL_CLASS:
     312     4543992 :                         if (ce->default_properties_table) {
     313     1200744 :                                 zval *p = ce->default_properties_table;
     314     1200744 :                                 zval *end = p + ce->default_properties_count;
     315             : 
     316     8946720 :                                 while (p != end) {
     317     6545232 :                                         zval_internal_ptr_dtor(p);
     318     6545232 :                                         p++;
     319             :                                 }
     320     1200744 :                                 free(ce->default_properties_table);
     321             :                         }
     322     4543992 :                         if (ce->default_static_members_table) {
     323           0 :                                 zval *p = ce->default_static_members_table;
     324           0 :                                 zval *end = p + ce->default_static_members_count;
     325             : 
     326           0 :                                 while (p != end) {
     327           0 :                                         zval_internal_ptr_dtor(p);
     328           0 :                                         p++;
     329             :                                 }
     330           0 :                                 free(ce->default_static_members_table);
     331             :                         }
     332     4543992 :                         zend_hash_destroy(&ce->properties_info);
     333     4543992 :                         zend_string_release(ce->name);
     334     4543992 :                         zend_hash_destroy(&ce->function_table);
     335     4543992 :                         if (zend_hash_num_elements(&ce->constants_table)) {
     336             :                                 zend_class_constant *c;
     337             : 
     338    57023568 :                                 ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
     339    27946728 :                                         zval_internal_ptr_dtor(&c->value);
     340    27946728 :                                         if (c->doc_comment && c->ce == ce) {
     341           0 :                                                 zend_string_release(c->doc_comment);
     342             :                                         }
     343             :                                 } ZEND_HASH_FOREACH_END();
     344     1130112 :                                 zend_hash_destroy(&ce->constants_table);
     345             :                         }
     346     4543992 :                         if (ce->num_interfaces > 0) {
     347     2354400 :                                 free(ce->interfaces);
     348             :                         }
     349     4543992 :                         free(ce);
     350             :                         break;
     351             :         }
     352             : }
     353             : 
     354           0 : void zend_class_add_ref(zval *zv)
     355             : {
     356           0 :         zend_class_entry *ce = Z_PTR_P(zv);
     357             : 
     358           0 :         ce->refcount++;
     359           0 : }
     360             : 
     361       93880 : ZEND_API void destroy_op_array(zend_op_array *op_array)
     362             : {
     363       93880 :         zval *literal = op_array->literals;
     364             :         zval *end;
     365             :         uint32_t i;
     366             : 
     367       96326 :         if (op_array->static_variables &&
     368        2446 :             !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
     369        2445 :                 if (--GC_REFCOUNT(op_array->static_variables) == 0) {
     370        2445 :                         zend_array_destroy(op_array->static_variables);
     371             :                 }
     372             :         }
     373             : 
     374       93880 :         if (op_array->run_time_cache && !op_array->function_name) {
     375       32065 :                 efree(op_array->run_time_cache);
     376       32065 :                 op_array->run_time_cache = NULL;
     377             :         }
     378             : 
     379       93880 :         if (!op_array->refcount || --(*op_array->refcount) > 0) {
     380       21993 :                 return;
     381             :         }
     382             : 
     383       71887 :         efree_size(op_array->refcount, sizeof(*(op_array->refcount)));
     384             : 
     385       71887 :         if (op_array->vars) {
     386       53416 :                 i = op_array->last_var;
     387      340238 :                 while (i > 0) {
     388      233406 :                         i--;
     389      233406 :                         zend_string_release(op_array->vars[i]);
     390             :                 }
     391       53416 :                 efree(op_array->vars);
     392             :         }
     393             : 
     394       71887 :         if (literal) {
     395       71830 :                 end = literal + op_array->last_literal;
     396     1340484 :                 while (literal < end) {
     397             :                         zval_ptr_dtor_nogc(literal);
     398     1196824 :                         literal++;
     399             :                 }
     400       71830 :                 efree(op_array->literals);
     401             :         }
     402       71887 :         efree(op_array->opcodes);
     403             : 
     404       71887 :         if (op_array->function_name) {
     405       40114 :                 zend_string_release(op_array->function_name);
     406             :         }
     407       71887 :         if (op_array->doc_comment) {
     408        2432 :                 zend_string_release(op_array->doc_comment);
     409             :         }
     410       71887 :         if (op_array->live_range) {
     411       17963 :                 efree(op_array->live_range);
     412             :         }
     413       71887 :         if (op_array->try_catch_array) {
     414        2144 :                 efree(op_array->try_catch_array);
     415             :         }
     416       71887 :         if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR) {
     417           0 :                 if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) {
     418           0 :                         zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array);
     419             :                 }
     420             :         }
     421       71887 :         if (op_array->arg_info) {
     422       29906 :                 uint32_t num_args = op_array->num_args;
     423       29906 :                 zend_arg_info *arg_info = op_array->arg_info;
     424             : 
     425       29906 :                 if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
     426         151 :                         arg_info--;
     427         151 :                         num_args++;
     428             :                 }
     429       29906 :                 if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
     430          40 :                         num_args++;
     431             :                 }
     432      119565 :                 for (i = 0 ; i < num_args; i++) {
     433       89659 :                         if (arg_info[i].name) {
     434       89508 :                                 zend_string_release(arg_info[i].name);
     435             :                         }
     436       89659 :                         if (arg_info[i].class_name) {
     437         249 :                                 zend_string_release(arg_info[i].class_name);
     438             :                         }
     439             :                 }
     440       29906 :                 efree(arg_info);
     441             :         }
     442             : }
     443             : 
     444     2687925 : void init_op(zend_op *op)
     445             : {
     446     2687925 :         memset(op, 0, sizeof(zend_op));
     447     2687925 :         op->lineno = CG(zend_lineno);
     448     2687925 :         SET_UNUSED(op->result);
     449     2687925 : }
     450             : 
     451     2528774 : zend_op *get_next_op(zend_op_array *op_array)
     452             : {
     453     2528774 :         uint32_t next_op_num = op_array->last++;
     454             :         zend_op *next_op;
     455             : 
     456     2528774 :         if (next_op_num >= CG(context).opcodes_size) {
     457        9018 :                 CG(context).opcodes_size *= 4;
     458        9018 :                 op_array_alloc_ops(op_array, CG(context).opcodes_size);
     459             :         }
     460             : 
     461     2528774 :         next_op = &(op_array->opcodes[next_op_num]);
     462             : 
     463     2528774 :         init_op(next_op);
     464             : 
     465     2528774 :         return next_op;
     466             : }
     467             : 
     468      886955 : uint32_t get_next_op_number(zend_op_array *op_array)
     469             : {
     470      886955 :         return op_array->last;
     471             : }
     472             : 
     473       17180 : zend_brk_cont_element *get_next_brk_cont_element(void)
     474             : {
     475       17180 :         CG(context).last_brk_cont++;
     476       17180 :         CG(context).brk_cont_array = erealloc(CG(context).brk_cont_array, sizeof(zend_brk_cont_element) * CG(context).last_brk_cont);
     477       17180 :         return &CG(context).brk_cont_array[CG(context).last_brk_cont-1];
     478             : }
     479             : 
     480           0 : static void zend_update_extended_info(zend_op_array *op_array)
     481             : {
     482           0 :         zend_op *opline = op_array->opcodes, *end=opline+op_array->last;
     483             : 
     484           0 :         while (opline<end) {
     485           0 :                 if (opline->opcode == ZEND_EXT_STMT) {
     486           0 :                         if (opline+1<end) {
     487           0 :                                 if ((opline+1)->opcode == ZEND_EXT_STMT) {
     488           0 :                                         opline->opcode = ZEND_NOP;
     489           0 :                                         opline++;
     490           0 :                                         continue;
     491             :                                 }
     492           0 :                                 if (opline+1<end) {
     493           0 :                                         opline->lineno = (opline+1)->lineno;
     494             :                                 }
     495             :                         } else {
     496           0 :                                 opline->opcode = ZEND_NOP;
     497             :                         }
     498             :                 }
     499           0 :                 opline++;
     500             :         }
     501           0 : }
     502             : 
     503           0 : static void zend_extension_op_array_handler(zend_extension *extension, zend_op_array *op_array)
     504             : {
     505           0 :         if (extension->op_array_handler) {
     506           0 :                 extension->op_array_handler(op_array);
     507             :         }
     508           0 : }
     509             : 
     510          29 : static void zend_check_finally_breakout(zend_op_array *op_array, uint32_t op_num, uint32_t dst_num)
     511             : {
     512             :         int i;
     513             : 
     514          85 :         for (i = 0; i < op_array->last_try_catch; i++) {
     515         177 :                 if ((op_num < op_array->try_catch_array[i].finally_op ||
     516          27 :                                         op_num >= op_array->try_catch_array[i].finally_end)
     517          52 :                                 && (dst_num >= op_array->try_catch_array[i].finally_op &&
     518          35 :                                          dst_num <= op_array->try_catch_array[i].finally_end)) {
     519           3 :                         CG(in_compilation) = 1;
     520           3 :                         CG(active_op_array) = op_array;
     521           3 :                         CG(zend_lineno) = op_array->opcodes[op_num].lineno;
     522           3 :                         zend_error_noreturn(E_COMPILE_ERROR, "jump into a finally block is disallowed");
     523         165 :                 } else if ((op_num >= op_array->try_catch_array[i].finally_op
     524          86 :                                         && op_num <= op_array->try_catch_array[i].finally_end)
     525          11 :                                 && (dst_num > op_array->try_catch_array[i].finally_end
     526          19 :                                         || dst_num < op_array->try_catch_array[i].finally_op)) {
     527           4 :                         CG(in_compilation) = 1;
     528           4 :                         CG(active_op_array) = op_array;
     529           4 :                         CG(zend_lineno) = op_array->opcodes[op_num].lineno;
     530           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "jump out of a finally block is disallowed");
     531             :                 }
     532             :         }
     533          22 : }
     534             : 
     535        2359 : static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) {
     536        2359 :         int nest_levels = opline->op2.num;
     537        2359 :         int array_offset = opline->op1.num;
     538             :         zend_brk_cont_element *jmp_to;
     539             :         do {
     540        2385 :                 jmp_to = &CG(context).brk_cont_array[array_offset];
     541        2385 :                 if (nest_levels > 1) {
     542          26 :                         array_offset = jmp_to->parent;
     543             :                 }
     544        2385 :         } while (--nest_levels > 0);
     545             : 
     546        2359 :         return opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont;
     547             : }
     548             : 
     549       74050 : ZEND_API int pass_two(zend_op_array *op_array)
     550             : {
     551             :         zend_op *opline, *end;
     552             : 
     553       74050 :         if (!ZEND_USER_CODE(op_array->type)) {
     554           0 :                 return 0;
     555             :         }
     556       74050 :         if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
     557           0 :                 zend_update_extended_info(op_array);
     558             :         }
     559       74050 :         if (CG(compiler_options) & ZEND_COMPILE_HANDLE_OP_ARRAY) {
     560       73817 :                 if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_HANDLER) {
     561           0 :                         zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array);
     562             :                 }
     563             :         }
     564             : 
     565       74050 :         if (CG(context).vars_size != op_array->last_var) {
     566       53990 :                 op_array->vars = (zend_string**) erealloc(op_array->vars, sizeof(zend_string*)*op_array->last_var);
     567       53990 :                 CG(context).vars_size = op_array->last_var;
     568             :         }
     569       74050 :         if (CG(context).opcodes_size != op_array->last) {
     570       73878 :                 op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last);
     571       73878 :                 CG(context).opcodes_size = op_array->last;
     572             :         }
     573       74050 :         if (CG(context).literals_size != op_array->last_literal) {
     574       71745 :                 op_array->literals = (zval*)erealloc(op_array->literals, sizeof(zval) * op_array->last_literal);
     575       71745 :                 CG(context).literals_size = op_array->last_literal;
     576             :         }
     577       74050 :         opline = op_array->opcodes;
     578       74050 :         end = opline + op_array->last;
     579     2676281 :         while (opline < end) {
     580     2528193 :                 switch (opline->opcode) {
     581             :                         case ZEND_FAST_CALL:
     582         216 :                                 opline->op1.opline_num = op_array->try_catch_array[opline->op1.num].finally_op;
     583         216 :                                 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
     584         216 :                                 break;
     585             :                         case ZEND_BRK:
     586             :                         case ZEND_CONT:
     587             :                                 {
     588        2359 :                                         uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
     589             : 
     590        2359 :                                         if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     591          13 :                                                 zend_check_finally_breakout(op_array, opline - op_array->opcodes, jmp_target);
     592             :                                         }
     593        2357 :                                         opline->opcode = ZEND_JMP;
     594        2357 :                                         opline->op1.opline_num = jmp_target;
     595        2357 :                                         opline->op2.num = 0;
     596        2357 :                                         ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
     597             :                                 }
     598        2357 :                                 break;
     599             :                         case ZEND_GOTO:
     600          47 :                                 zend_resolve_goto_label(op_array, opline);
     601          42 :                                 if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
     602          16 :                                         zend_check_finally_breakout(op_array, opline - op_array->opcodes, opline->op1.opline_num);
     603             :                                 }
     604             :                                 /* break omitted intentionally */
     605             :                         case ZEND_JMP:
     606       69155 :                                 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
     607       69155 :                                 break;
     608             :                         case ZEND_JMPZNZ:
     609             :                                 /* absolute index to relative offset */
     610           0 :                                 opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
     611             :                                 /* break omitted intentionally */
     612             :                         case ZEND_JMPZ:
     613             :                         case ZEND_JMPNZ:
     614             :                         case ZEND_JMPZ_EX:
     615             :                         case ZEND_JMPNZ_EX:
     616             :                         case ZEND_JMP_SET:
     617             :                         case ZEND_COALESCE:
     618             :                         case ZEND_FE_RESET_R:
     619             :                         case ZEND_FE_RESET_RW:
     620      140778 :                                 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
     621      140778 :                                 break;
     622             :                         case ZEND_ASSERT_CHECK:
     623             :                         {
     624             :                                 /* If result of assert is unused, result of check is unused as well */
     625         232 :                                 zend_op *call = &op_array->opcodes[opline->op2.opline_num - 1];
     626         232 :                                 if (call->opcode == ZEND_EXT_FCALL_END) {
     627           0 :                                         call--;
     628             :                                 }
     629         232 :                                 if (call->result_type == IS_UNUSED) {
     630         192 :                                         opline->result_type = IS_UNUSED;
     631             :                                 }
     632         232 :                                 ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
     633         232 :                                 break;
     634             :                         }
     635             :                         case ZEND_DECLARE_ANON_CLASS:
     636             :                         case ZEND_DECLARE_ANON_INHERITED_CLASS:
     637             :                         case ZEND_CATCH:
     638             :                         case ZEND_FE_FETCH_R:
     639             :                         case ZEND_FE_FETCH_RW:
     640             :                                 /* absolute index to relative offset */
     641       14892 :                                 opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
     642       14892 :                                 break;
     643             :                         case ZEND_RETURN:
     644             :                         case ZEND_RETURN_BY_REF:
     645      120409 :                                 if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
     646         236 :                                         opline->opcode = ZEND_GENERATOR_RETURN;
     647             :                                 }
     648             :                                 break;
     649             :                 }
     650     2528181 :                 if (opline->op1_type == IS_CONST) {
     651      487606 :                         ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
     652     2040575 :                 } else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
     653      568722 :                         opline->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op1.var);
     654             :                 }
     655     2528181 :                 if (opline->op2_type == IS_CONST) {
     656      632615 :                         ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
     657     1895566 :                 } else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
     658      137821 :                         opline->op2.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op2.var);
     659             :                 }
     660     2528181 :                 if (opline->result_type & (IS_VAR|IS_TMP_VAR)) {
     661      760580 :                         opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->result.var);
     662             :                 }
     663     2528181 :                 ZEND_VM_SET_OPCODE_HANDLER(opline);
     664     2528181 :                 opline++;
     665             :         }
     666             : 
     667       74038 :         if (op_array->live_range) {
     668             :                 int i;
     669             : 
     670       65127 :                 for (i = 0; i < op_array->last_live_range; i++) {
     671       93878 :                         op_array->live_range[i].var =
     672       93878 :                                 (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + (op_array->live_range[i].var / sizeof(zval))) |
     673       46939 :                                 (op_array->live_range[i].var & ZEND_LIVE_MASK);
     674             :                 }
     675             :         }
     676             : 
     677       74038 :         op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
     678       74038 :         return 0;
     679             : }
     680             : 
     681         427 : ZEND_API unary_op_type get_unary_op(int opcode)
     682             : {
     683         427 :         switch (opcode) {
     684             :                 case ZEND_BW_NOT:
     685          84 :                         return (unary_op_type) bitwise_not_function;
     686             :                 case ZEND_BOOL_NOT:
     687         343 :                         return (unary_op_type) boolean_not_function;
     688             :                 default:
     689           0 :                         return (unary_op_type) NULL;
     690             :         }
     691             : }
     692             : 
     693       12909 : ZEND_API binary_op_type get_binary_op(int opcode)
     694             : {
     695       12909 :         switch (opcode) {
     696             :                 case ZEND_ADD:
     697             :                 case ZEND_ASSIGN_ADD:
     698         257 :                         return (binary_op_type) add_function;
     699             :                 case ZEND_SUB:
     700             :                 case ZEND_ASSIGN_SUB:
     701         206 :                         return (binary_op_type) sub_function;
     702             :                 case ZEND_MUL:
     703             :                 case ZEND_ASSIGN_MUL:
     704        6995 :                         return (binary_op_type) mul_function;
     705             :                 case ZEND_POW:
     706          11 :                         return (binary_op_type) pow_function;
     707             :                 case ZEND_DIV:
     708             :                 case ZEND_ASSIGN_DIV:
     709          35 :                         return (binary_op_type) div_function;
     710             :                 case ZEND_MOD:
     711             :                 case ZEND_ASSIGN_MOD:
     712          12 :                         return (binary_op_type) mod_function;
     713             :                 case ZEND_SL:
     714             :                 case ZEND_ASSIGN_SL:
     715          37 :                         return (binary_op_type) shift_left_function;
     716             :                 case ZEND_SR:
     717             :                 case ZEND_ASSIGN_SR:
     718           5 :                         return (binary_op_type) shift_right_function;
     719             :                 case ZEND_FAST_CONCAT:
     720             :                 case ZEND_CONCAT:
     721             :                 case ZEND_ASSIGN_CONCAT:
     722        4102 :                         return (binary_op_type) concat_function;
     723             :                 case ZEND_IS_IDENTICAL:
     724           4 :                         return (binary_op_type) is_identical_function;
     725             :                 case ZEND_IS_NOT_IDENTICAL:
     726          19 :                         return (binary_op_type) is_not_identical_function;
     727             :                 case ZEND_IS_EQUAL:
     728          81 :                         return (binary_op_type) is_equal_function;
     729             :                 case ZEND_IS_NOT_EQUAL:
     730         415 :                         return (binary_op_type) is_not_equal_function;
     731             :                 case ZEND_IS_SMALLER:
     732          46 :                         return (binary_op_type) is_smaller_function;
     733             :                 case ZEND_IS_SMALLER_OR_EQUAL:
     734           1 :                         return (binary_op_type) is_smaller_or_equal_function;
     735             :                 case ZEND_SPACESHIP:
     736           3 :                         return (binary_op_type) compare_function;
     737             :                 case ZEND_BW_OR:
     738             :                 case ZEND_ASSIGN_BW_OR:
     739         581 :                         return (binary_op_type) bitwise_or_function;
     740             :                 case ZEND_BW_AND:
     741             :                 case ZEND_ASSIGN_BW_AND:
     742          84 :                         return (binary_op_type) bitwise_and_function;
     743             :                 case ZEND_BW_XOR:
     744             :                 case ZEND_ASSIGN_BW_XOR:
     745          13 :                         return (binary_op_type) bitwise_xor_function;
     746             :                 case ZEND_BOOL_XOR:
     747           2 :                         return (binary_op_type) boolean_xor_function;
     748             :                 default:
     749           0 :                         return (binary_op_type) NULL;
     750             :         }
     751             : }
     752             : 
     753             : /*
     754             :  * Local variables:
     755             :  * tab-width: 4
     756             :  * c-basic-offset: 4
     757             :  * indent-tabs-mode: t
     758             :  * End:
     759             :  */

Generated by: LCOV version 1.10

Generated at Wed, 24 Aug 2016 12:20:16 +0000 (3 days ago)

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