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_execute_API.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 659 768 85.8 %
Date: 2016-06-25 Functions: 41 46 89.1 %
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             : #include <signal.h>
      25             : 
      26             : #include "zend.h"
      27             : #include "zend_compile.h"
      28             : #include "zend_execute.h"
      29             : #include "zend_API.h"
      30             : #include "zend_stack.h"
      31             : #include "zend_constants.h"
      32             : #include "zend_extensions.h"
      33             : #include "zend_exceptions.h"
      34             : #include "zend_closures.h"
      35             : #include "zend_generators.h"
      36             : #include "zend_vm.h"
      37             : #include "zend_float.h"
      38             : #ifdef HAVE_SYS_TIME_H
      39             : #include <sys/time.h>
      40             : #endif
      41             : 
      42             : ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data);
      43             : ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value);
      44             : 
      45             : /* true globals */
      46             : ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, NULL, NULL, 0, 0 };
      47             : ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL };
      48             : 
      49             : #ifdef ZEND_WIN32
      50             : ZEND_TLS HANDLE tq_timer = NULL;
      51             : #endif
      52             : 
      53             : #if 0&&ZEND_DEBUG
      54             : static void (*original_sigsegv_handler)(int);
      55             : static void zend_handle_sigsegv(int dummy) /* {{{ */
      56             : {
      57             :         fflush(stdout);
      58             :         fflush(stderr);
      59             :         if (original_sigsegv_handler == zend_handle_sigsegv) {
      60             :                 signal(SIGSEGV, original_sigsegv_handler);
      61             :         } else {
      62             :                 signal(SIGSEGV, SIG_DFL);
      63             :         }
      64             :         {
      65             : 
      66             :                 fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
      67             :                                 active_opline->opcode,
      68             :                                 active_opline-EG(active_op_array)->opcodes,
      69             :                                 get_active_function_name(),
      70             :                                 zend_get_executed_filename(),
      71             :                                 zend_get_executed_lineno());
      72             : /* See http://support.microsoft.com/kb/190351 */
      73             : #ifdef ZEND_WIN32
      74             :                 fflush(stderr);
      75             : #endif
      76             :         }
      77             :         if (original_sigsegv_handler!=zend_handle_sigsegv) {
      78             :                 original_sigsegv_handler(dummy);
      79             :         }
      80             : }
      81             : /* }}} */
      82             : #endif
      83             : 
      84       22412 : static void zend_extension_activator(zend_extension *extension) /* {{{ */
      85             : {
      86       22412 :         if (extension->activate) {
      87         378 :                 extension->activate();
      88             :         }
      89       22412 : }
      90             : /* }}} */
      91             : 
      92       22453 : static void zend_extension_deactivator(zend_extension *extension) /* {{{ */
      93             : {
      94       22453 :         if (extension->deactivate) {
      95         378 :                 extension->deactivate();
      96             :         }
      97       22453 : }
      98             : /* }}} */
      99             : 
     100       45503 : static int clean_non_persistent_function(zval *zv) /* {{{ */
     101             : {
     102       45503 :         zend_function *function = Z_PTR_P(zv);
     103       45503 :         return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
     104             : }
     105             : /* }}} */
     106             : 
     107           0 : ZEND_API int clean_non_persistent_function_full(zval *zv) /* {{{ */
     108             : {
     109           0 :         zend_function *function = Z_PTR_P(zv);
     110           0 :         return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
     111             : }
     112             : /* }}} */
     113             : 
     114       32248 : static int clean_non_persistent_class(zval *zv) /* {{{ */
     115             : {
     116       32248 :         zend_class_entry *ce = Z_PTR_P(zv);
     117       32248 :         return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
     118             : }
     119             : /* }}} */
     120             : 
     121           0 : ZEND_API int clean_non_persistent_class_full(zval *zv) /* {{{ */
     122             : {
     123           0 :         zend_class_entry *ce = Z_PTR_P(zv);
     124           0 :         return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
     125             : }
     126             : /* }}} */
     127             : 
     128       22541 : void init_executor(void) /* {{{ */
     129             : {
     130       22541 :         zend_init_fpu();
     131             : 
     132       22541 :         ZVAL_NULL(&EG(uninitialized_zval));
     133       22541 :         ZVAL_ERROR(&EG(error_zval));
     134             : /* destroys stack frame, therefore makes core dumps worthless */
     135             : #if 0&&ZEND_DEBUG
     136             :         original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
     137             : #endif
     138             : 
     139       22541 :         EG(symtable_cache_ptr) = EG(symtable_cache) - 1;
     140       22541 :         EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1;
     141       22541 :         EG(no_extensions) = 0;
     142             : 
     143       22541 :         EG(function_table) = CG(function_table);
     144       22541 :         EG(class_table) = CG(class_table);
     145             : 
     146       22541 :         EG(in_autoload) = NULL;
     147       22541 :         EG(autoload_func) = NULL;
     148       22541 :         EG(error_handling) = EH_NORMAL;
     149             : 
     150       22541 :         zend_vm_stack_init();
     151             : 
     152       22541 :         zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
     153       22541 :         EG(valid_symbol_table) = 1;
     154             : 
     155       22541 :         zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
     156             : 
     157       22541 :         zend_hash_init(&EG(included_files), 8, NULL, NULL, 0);
     158             : 
     159       22541 :         EG(ticks_count) = 0;
     160             : 
     161       22541 :         ZVAL_UNDEF(&EG(user_error_handler));
     162             : 
     163       22541 :         EG(current_execute_data) = NULL;
     164             : 
     165       22541 :         zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
     166       22541 :         zend_stack_init(&EG(user_error_handlers), sizeof(zval));
     167       22541 :         zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
     168             : 
     169       22541 :         zend_objects_store_init(&EG(objects_store), 1024);
     170             : 
     171       22541 :         EG(full_tables_cleanup) = 0;
     172             : #ifdef ZEND_WIN32
     173             :         EG(timed_out) = 0;
     174             : #endif
     175             : 
     176       22541 :         EG(exception) = NULL;
     177       22541 :         EG(prev_exception) = NULL;
     178             : 
     179       22541 :         EG(scope) = NULL;
     180             : 
     181       22541 :         EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
     182       22541 :         EG(ht_iterators_used) = 0;
     183       22541 :         EG(ht_iterators) = EG(ht_iterators_slots);
     184       22541 :         memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));
     185             : 
     186       22541 :         EG(active) = 1;
     187       22541 : }
     188             : /* }}} */
     189             : 
     190      290190 : static int zval_call_destructor(zval *zv) /* {{{ */
     191             : {
     192      290190 :         if (Z_TYPE_P(zv) == IS_INDIRECT) {
     193        2651 :                 zv = Z_INDIRECT_P(zv);
     194             :         }
     195      299964 :         if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
     196        9018 :                 return ZEND_HASH_APPLY_REMOVE;
     197             :         } else {
     198      281172 :                 return ZEND_HASH_APPLY_KEEP;
     199             :         }
     200             : }
     201             : /* }}} */
     202             : 
     203       19287 : static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
     204             : {
     205       19287 :         if (Z_TYPE_P(zv) == IS_INDIRECT) {
     206        2317 :                 zv = Z_INDIRECT_P(zv);
     207             :         }
     208             :         i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC);
     209       19287 : }
     210             : /* }}} */
     211             : 
     212          47 : static void zend_throw_or_error(int fetch_type, zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
     213             : {
     214             :         va_list va;
     215          47 :         char *message = NULL;
     216             : 
     217          47 :         va_start(va, format);
     218          47 :         zend_vspprintf(&message, 0, format, va);
     219             : 
     220          47 :         if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) {
     221          34 :                 zend_throw_error(exception_ce, "%s", message);
     222             :         } else {
     223          13 :                 zend_error(E_ERROR, "%s", message);
     224             :         }
     225             : 
     226          34 :         efree(message);
     227          34 :         va_end(va);
     228          34 : }
     229             : /* }}} */
     230             : 
     231       22579 : void shutdown_destructors(void) /* {{{ */
     232             : {
     233       22579 :         if (CG(unclean_shutdown)) {
     234        2152 :                 EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
     235             :         }
     236       22579 :         zend_try {
     237             :                 uint32_t symbols;
     238             :                 do {
     239       27852 :                         symbols = zend_hash_num_elements(&EG(symbol_table));
     240       27852 :                         zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
     241       27852 :                 } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
     242       22579 :                 zend_objects_store_call_destructors(&EG(objects_store));
     243           0 :         } zend_catch {
     244             :                 /* if we couldn't destruct cleanly, mark all objects as destructed anyway */
     245           0 :                 zend_objects_store_mark_destructed(&EG(objects_store));
     246       22579 :         } zend_end_try();
     247       22579 : }
     248             : /* }}} */
     249             : 
     250       22579 : void shutdown_executor(void) /* {{{ */
     251             : {
     252             :         zend_function *func;
     253             :         zend_class_entry *ce;
     254             : 
     255       22579 :         zend_try {
     256             : 
     257             : /* Removed because this can not be safely done, e.g. in this situation:
     258             :    Object 1 creates object 2
     259             :    Object 3 holds reference to object 2.
     260             :    Now when 1 and 2 are destroyed, 3 can still access 2 in its destructor, with
     261             :    very problematic results */
     262             : /*              zend_objects_store_call_destructors(&EG(objects_store)); */
     263             : 
     264             : /* Moved after symbol table cleaners, because  some of the cleaners can call
     265             :    destructors, which would use EG(symtable_cache_ptr) and thus leave leaks */
     266             : /*              while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
     267             :                         zend_hash_destroy(*EG(symtable_cache_ptr));
     268             :                         efree(*EG(symtable_cache_ptr));
     269             :                         EG(symtable_cache_ptr)--;
     270             :                 }
     271             : */
     272       22579 :                 zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
     273             : 
     274       22579 :                 if (CG(unclean_shutdown)) {
     275        2159 :                         EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
     276             :                 }
     277       22579 :                 zend_hash_graceful_reverse_destroy(&EG(symbol_table));
     278       22579 :         } zend_end_try();
     279       22579 :         EG(valid_symbol_table) = 0;
     280             : 
     281       22579 :         zend_try {
     282             :                 zval *zeh;
     283             :                 /* remove error handlers before destroying classes and functions,
     284             :                  * so that if handler used some class, crash would not happen */
     285       22579 :                 if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
     286         244 :                         zeh = &EG(user_error_handler);
     287         244 :                         zval_ptr_dtor(zeh);
     288         244 :                         ZVAL_UNDEF(&EG(user_error_handler));
     289             :                 }
     290             : 
     291       22579 :                 if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
     292          11 :                         zeh = &EG(user_exception_handler);
     293          11 :                         zval_ptr_dtor(zeh);
     294          11 :                         ZVAL_UNDEF(&EG(user_exception_handler));
     295             :                 }
     296             : 
     297       22579 :                 zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
     298       22579 :                 zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1);
     299       22579 :                 zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1);
     300       22579 :         } zend_end_try();
     301             : 
     302       22579 :         zend_try {
     303             :                 /* Cleanup static data for functions and arrays.
     304             :                  * We need a separate cleanup stage because of the following problem:
     305             :                  * Suppose we destroy class X, which destroys the class's function table,
     306             :                  * and in the function table we have function foo() that has static $bar.
     307             :                  * Now if an object of class X is assigned to $bar, its destructor will be
     308             :                  * called and will fail since X's function table is in mid-destruction.
     309             :                  * So we want first of all to clean up all data and then move to tables destruction.
     310             :                  * Note that only run-time accessed data need to be cleaned up, pre-defined data can
     311             :                  * not contain objects and thus are not probelmatic */
     312       22579 :                 if (EG(full_tables_cleanup)) {
     313           0 :                         ZEND_HASH_FOREACH_PTR(EG(function_table), func) {
     314           0 :                                 if (func->type == ZEND_USER_FUNCTION) {
     315           0 :                                         zend_cleanup_op_array_data((zend_op_array *) func);
     316             :                                 }
     317             :                         } ZEND_HASH_FOREACH_END();
     318           0 :                         ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) {
     319           0 :                                 if (ce->type == ZEND_USER_CLASS) {
     320           0 :                                         zend_cleanup_user_class_data(ce);
     321             :                                 } else {
     322           0 :                                         zend_cleanup_internal_class_data(ce);
     323             :                                 }
     324             :                         } ZEND_HASH_FOREACH_END();
     325             :                 } else {
     326      119248 :                         ZEND_HASH_REVERSE_FOREACH_PTR(EG(function_table), func) {
     327       45503 :                                 if (func->type != ZEND_USER_FUNCTION) {
     328       22579 :                                         break;
     329             :                                 }
     330       22924 :                                 zend_cleanup_op_array_data((zend_op_array *) func);
     331             :                         } ZEND_HASH_FOREACH_END();
     332       76398 :                         ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) {
     333       32246 :                                 if (ce->type != ZEND_USER_CLASS) {
     334       22577 :                                         break;
     335             :                                 }
     336        9669 :                                 zend_cleanup_user_class_data(ce);
     337             :                         } ZEND_HASH_FOREACH_END();
     338       22577 :                         zend_cleanup_internal_classes();
     339             :                 }
     340       22579 :         } zend_end_try();
     341             : 
     342       22579 :         zend_try {
     343       22579 :                 zend_llist_destroy(&CG(open_files));
     344       22579 :         } zend_end_try();
     345             : 
     346       22579 :         zend_try {
     347       22579 :                 zend_close_rsrc_list(&EG(regular_list));
     348       22579 :         } zend_end_try();
     349             : 
     350             : #if ZEND_DEBUG
     351             :         if (GC_G(gc_enabled) && !CG(unclean_shutdown)) {
     352             :                 gc_collect_cycles();
     353             :         }
     354             : #endif
     355             : 
     356       22579 :         zend_try {
     357       22579 :                 zend_objects_store_free_object_storage(&EG(objects_store));
     358             : 
     359       22579 :                 zend_vm_stack_destroy();
     360             : 
     361             :                 /* Destroy all op arrays */
     362       22579 :                 if (EG(full_tables_cleanup)) {
     363           0 :                         zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
     364           0 :                         zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
     365             :                 } else {
     366       22579 :                         zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function);
     367       22579 :                         zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class);
     368             :                 }
     369             : 
     370       45406 :                 while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
     371         248 :                         zend_hash_destroy(*EG(symtable_cache_ptr));
     372         248 :                         FREE_HASHTABLE(*EG(symtable_cache_ptr));
     373         248 :                         EG(symtable_cache_ptr)--;
     374             :                 }
     375       22579 :         } zend_end_try();
     376             : 
     377       22579 :         zend_try {
     378       22579 :                 clean_non_persistent_constants();
     379       22579 :         } zend_end_try();
     380             : 
     381       22579 :         zend_try {
     382             : #if 0&&ZEND_DEBUG
     383             :         signal(SIGSEGV, original_sigsegv_handler);
     384             : #endif
     385             : 
     386       22579 :                 zend_hash_destroy(&EG(included_files));
     387             : 
     388       22579 :                 zend_stack_destroy(&EG(user_error_handlers_error_reporting));
     389       22579 :                 zend_stack_destroy(&EG(user_error_handlers));
     390       22579 :                 zend_stack_destroy(&EG(user_exception_handlers));
     391       22579 :                 zend_objects_store_destroy(&EG(objects_store));
     392       22579 :                 if (EG(in_autoload)) {
     393          92 :                         zend_hash_destroy(EG(in_autoload));
     394          92 :                         FREE_HASHTABLE(EG(in_autoload));
     395             :                 }
     396       22579 :         } zend_end_try();
     397             : 
     398       22579 :         zend_shutdown_fpu();
     399             : 
     400             : #ifdef ZEND_DEBUG
     401       22579 :         if (EG(ht_iterators_used)) {
     402           0 :                 zend_error(E_WARNING, "Leaked %" PRIu32 " hashtable iterators", EG(ht_iterators_used));
     403             :         }
     404             : #endif
     405             : 
     406       22579 :         EG(ht_iterators_used) = 0;
     407       22579 :         if (EG(ht_iterators) != EG(ht_iterators_slots)) {
     408           0 :                 efree(EG(ht_iterators));
     409             :         }
     410             : 
     411       22579 :         EG(active) = 0;
     412       22579 : }
     413             : /* }}} */
     414             : 
     415             : /* return class name and "::" or "". */
     416      224952 : ZEND_API const char *get_active_class_name(const char **space) /* {{{ */
     417             : {
     418             :         zend_function *func;
     419             : 
     420      224952 :         if (!zend_is_executing()) {
     421           0 :                 if (space) {
     422           0 :                         *space = "";
     423             :                 }
     424           0 :                 return "";
     425             :         }
     426             : 
     427      224952 :         func = EG(current_execute_data)->func;
     428      224952 :         switch (func->type) {
     429             :                 case ZEND_USER_FUNCTION:
     430             :                 case ZEND_INTERNAL_FUNCTION:
     431             :                 {
     432      224952 :                         zend_class_entry *ce = func->common.scope;
     433             : 
     434      224952 :                         if (space) {
     435      224952 :                                 *space = ce ? "::" : "";
     436             :                         }
     437      224952 :                         return ce ? ZSTR_VAL(ce->name) : "";
     438             :                 }
     439             :                 default:
     440           0 :                         if (space) {
     441           0 :                                 *space = "";
     442             :                         }
     443           0 :                         return "";
     444             :         }
     445             : }
     446             : /* }}} */
     447             : 
     448      224976 : ZEND_API const char *get_active_function_name(void) /* {{{ */
     449             : {
     450             :         zend_function *func;
     451             : 
     452      224976 :         if (!zend_is_executing()) {
     453          16 :                 return NULL;
     454             :         }
     455      224960 :         func = EG(current_execute_data)->func;
     456      224960 :         switch (func->type) {
     457             :                 case ZEND_USER_FUNCTION: {
     458         207 :                                 zend_string *function_name = func->common.function_name;
     459             : 
     460         207 :                                 if (function_name) {
     461         150 :                                         return ZSTR_VAL(function_name);
     462             :                                 } else {
     463          57 :                                         return "main";
     464             :                                 }
     465             :                         }
     466             :                         break;
     467             :                 case ZEND_INTERNAL_FUNCTION:
     468      224753 :                         return ZSTR_VAL(func->common.function_name);
     469             :                         break;
     470             :                 default:
     471           0 :                         return NULL;
     472             :         }
     473             : }
     474             : /* }}} */
     475             : 
     476      425127 : ZEND_API const char *zend_get_executed_filename(void) /* {{{ */
     477             : {
     478      425127 :         zend_execute_data *ex = EG(current_execute_data);
     479             : 
     480     1087316 :         while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
     481      237062 :                 ex = ex->prev_execute_data;
     482             :         }
     483      425127 :         if (ex) {
     484      425100 :                 return ZSTR_VAL(ex->func->op_array.filename);
     485             :         } else {
     486          27 :                 return "[no active file]";
     487             :         }
     488             : }
     489             : /* }}} */
     490             : 
     491        6487 : ZEND_API zend_string *zend_get_executed_filename_ex(void) /* {{{ */
     492             : {
     493        6487 :         zend_execute_data *ex = EG(current_execute_data);
     494             : 
     495       13073 :         while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
     496          99 :                 ex = ex->prev_execute_data;
     497             :         }
     498        6487 :         if (ex) {
     499        6487 :                 return ex->func->op_array.filename;
     500             :         } else {
     501           0 :                 return NULL;
     502             :         }
     503             : }
     504             : /* }}} */
     505             : 
     506      424299 : ZEND_API uint zend_get_executed_lineno(void) /* {{{ */
     507             : {
     508      424299 :         zend_execute_data *ex = EG(current_execute_data);
     509             : 
     510     1085243 :         while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) {
     511      236645 :                 ex = ex->prev_execute_data;
     512             :         }
     513      424299 :         if (ex) {
     514      424292 :                 if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION &&
     515           8 :                     ex->opline->lineno == 0 && EG(opline_before_exception)) {
     516           4 :                         return EG(opline_before_exception)->lineno;
     517             :                 }
     518      424280 :                 return ex->opline->lineno;
     519             :         } else {
     520          15 :                 return 0;
     521             :         }
     522             : }
     523             : /* }}} */
     524             : 
     525      902433 : ZEND_API zend_bool zend_is_executing(void) /* {{{ */
     526             : {
     527      902433 :         return EG(current_execute_data) != 0;
     528             : }
     529             : /* }}} */
     530             : 
     531     7134343 : ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
     532             : {
     533             :         i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_RELAY_CC);
     534     7134342 : }
     535             : /* }}} */
     536             : 
     537    32961711 : ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
     538             : {
     539    32961711 :         if (Z_REFCOUNTED_P(zval_ptr)) {
     540             :                 Z_DELREF_P(zval_ptr);
     541     2262300 :                 if (Z_REFCOUNT_P(zval_ptr) == 0) {
     542      972789 :                         _zval_internal_dtor_for_ptr(zval_ptr ZEND_FILE_LINE_CC);
     543             :                 }
     544             :         }
     545    32961711 : }
     546             : /* }}} */
     547             : 
     548             : #define IS_VISITED_CONSTANT                     0x80
     549             : #define IS_CONSTANT_VISITED(p)          (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
     550             : #define MARK_CONSTANT_VISITED(p)        Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT
     551             : #define RESET_CONSTANT_VISITED(p)       Z_TYPE_INFO_P(p) &= ~IS_VISITED_CONSTANT
     552             : 
     553         659 : ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_class_entry *scope) /* {{{ */
     554             : {
     555             :         zval *const_value;
     556             :         char *colon;
     557             : 
     558         659 :         if (IS_CONSTANT_VISITED(p)) {
     559           2 :                 zend_throw_error(NULL, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
     560           2 :                 return FAILURE;
     561         657 :         } else if (Z_TYPE_P(p) == IS_CONSTANT) {
     562             : 
     563         473 :                 SEPARATE_ZVAL_NOREF(p);
     564         295 :                 MARK_CONSTANT_VISITED(p);
     565         295 :                 if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) {
     566             :                         ZEND_ASSERT(EG(current_execute_data));
     567           7 :                         if (inline_change) {
     568           6 :                                 zend_string_release(Z_STR_P(p));
     569             :                         }
     570          14 :                         if (EG(scope) && EG(scope)->name) {
     571           7 :                                 ZVAL_STR_COPY(p, EG(scope)->name);
     572             :                         } else {
     573           0 :                                 ZVAL_EMPTY_STRING(p);
     574             :                         }
     575         288 :                 } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) {
     576          26 :                         char *actual = Z_STRVAL_P(p);
     577             : 
     578          26 :                         if (UNEXPECTED(EG(exception))) {
     579           6 :                                 RESET_CONSTANT_VISITED(p);
     580           6 :                                 return FAILURE;
     581          40 :                         } else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
     582           0 :                                 zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(p));
     583           0 :                                 RESET_CONSTANT_VISITED(p);
     584           0 :                                 return FAILURE;
     585             :                         } else {
     586          20 :                                 zend_string *save = Z_STR_P(p);
     587             :                                 char *slash;
     588          20 :                                 size_t actual_len = Z_STRLEN_P(p);
     589          25 :                                 if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) {
     590           3 :                                         actual = slash + 1;
     591           3 :                                         actual_len -= (actual - Z_STRVAL_P(p));
     592           3 :                                         if (inline_change) {
     593           2 :                                                 zend_string *s = zend_string_init(actual, actual_len, 0);
     594           2 :                                                 Z_STR_P(p) = s;
     595           2 :                                                 Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE;
     596             :                                         }
     597             :                                 }
     598          20 :                                 if (actual[0] == '\\') {
     599           0 :                                         if (inline_change) {
     600           0 :                                                 memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p));
     601           0 :                                                 --Z_STRLEN_P(p);
     602             :                                         } else {
     603           0 :                                                 ++actual;
     604             :                                         }
     605           0 :                                         --actual_len;
     606             :                                 }
     607          20 :                                 if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
     608          15 :                                         if (ZSTR_VAL(save)[0] == '\\') {
     609           0 :                                                 zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(save) + 1);
     610             :                                         } else {
     611          15 :                                                 zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(save));
     612             :                                         }
     613          15 :                                         if (inline_change) {
     614             :                                                 zend_string_release(save);
     615             :                                         }
     616          15 :                                         RESET_CONSTANT_VISITED(p);
     617          15 :                                         return FAILURE;
     618             :                                 } else {
     619           5 :                                         zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",  actual,  actual);
     620           5 :                                         if (!inline_change) {
     621           2 :                                                 ZVAL_STRINGL(p, actual, actual_len);
     622             :                                         } else {
     623           4 :                                                 Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ?
     624             :                                                         IS_STRING_EX : IS_INTERNED_STRING_EX;
     625           4 :                                                 if (save && ZSTR_VAL(save) != actual) {
     626             :                                                         zend_string_release(save);
     627             :                                                 }
     628             :                                         }
     629             :                                 }
     630             :                         }
     631             :                 } else {
     632         256 :                         if (inline_change) {
     633         150 :                                 zend_string_release(Z_STR_P(p));
     634             :                         }
     635         256 :                         ZVAL_COPY_VALUE(p, const_value);
     636         256 :                         if (Z_OPT_CONSTANT_P(p)) {
     637           0 :                                 if (UNEXPECTED(zval_update_constant_ex(p, 1, NULL) != SUCCESS)) {
     638           0 :                                         RESET_CONSTANT_VISITED(p);
     639           0 :                                         return FAILURE;
     640             :                                 }
     641             :                         }
     642             :                         zval_opt_copy_ctor(p);
     643             :                 }
     644         362 :         } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) {
     645             :                 zval tmp;
     646             : 
     647         113 :                 if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) {
     648          18 :                         return FAILURE;
     649             :                 }
     650          93 :                 if (inline_change) {
     651          54 :                         zval_ptr_dtor(p);
     652             :                 }
     653          93 :                 ZVAL_COPY_VALUE(p, &tmp);
     654             :         }
     655         610 :         return SUCCESS;
     656             : }
     657             : /* }}} */
     658             : 
     659           0 : ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change) /* {{{ */
     660             : {
     661           0 :         return zval_update_constant_ex(pp, inline_change, NULL);
     662             : }
     663             : /* }}} */
     664             : 
     665        1836 : int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[]) /* {{{ */
     666             : {
     667        1836 :         return call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, 1, NULL);
     668             : }
     669             : /* }}} */
     670             : 
     671       11354 : int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation, zend_array *symbol_table) /* {{{ */
     672             : {
     673             :         zend_fcall_info fci;
     674             : 
     675       11354 :         fci.size = sizeof(fci);
     676       11354 :         fci.function_table = function_table;
     677       11354 :         fci.object = object ? Z_OBJ_P(object) : NULL;
     678       11354 :         ZVAL_COPY_VALUE(&fci.function_name, function_name);
     679       11354 :         fci.retval = retval_ptr;
     680       11354 :         fci.param_count = param_count;
     681       11354 :         fci.params = params;
     682       11354 :         fci.no_separation = (zend_bool) no_separation;
     683       11354 :         fci.symbol_table = symbol_table;
     684             : 
     685       11354 :         return zend_call_function(&fci, NULL);
     686             : }
     687             : /* }}} */
     688             : 
     689      705160 : int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */
     690             : {
     691             :         uint32_t i;
     692      705160 :         zend_class_entry *calling_scope = NULL;
     693             :         zend_execute_data *call, dummy_execute_data;
     694             :         zend_fcall_info_cache fci_cache_local;
     695             :         zend_function *func;
     696             :         zend_class_entry *orig_scope;
     697             : 
     698      705160 :         ZVAL_UNDEF(fci->retval);
     699             : 
     700      705160 :         if (!EG(active)) {
     701           0 :                 return FAILURE; /* executor is already inactive */
     702             :         }
     703             : 
     704      705160 :         if (EG(exception)) {
     705          11 :                 return FAILURE; /* we would result in an instable executor otherwise */
     706             :         }
     707             : 
     708      705149 :         switch (fci->size) {
     709             :                 case sizeof(zend_fcall_info):
     710      705149 :                         break; /* nothing to do currently */
     711             :                 default:
     712           0 :                         zend_error_noreturn(E_CORE_ERROR, "Corrupted fcall_info provided to zend_call_function()");
     713             :                         break;
     714             :         }
     715             : 
     716      705149 :         orig_scope = EG(scope);
     717             : 
     718             :         /* Initialize execute_data */
     719      705149 :         if (!EG(current_execute_data)) {
     720             :                 /* This only happens when we're called outside any execute()'s
     721             :                  * It shouldn't be strictly necessary to NULL execute_data out,
     722             :                  * but it may make bugs easier to spot
     723             :                  */
     724       20229 :                 memset(&dummy_execute_data, 0, sizeof(zend_execute_data));
     725       20229 :                 EG(current_execute_data) = &dummy_execute_data;
     726     1724728 :         } else if (EG(current_execute_data)->func &&
     727      684907 :                    ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
     728       88967 :                    EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL &&
     729       88648 :                    EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL &&
     730       88643 :                    EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL &&
     731       88643 :                    EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) {
     732             :                 /* Insert fake frame in case of include or magic calls */
     733       88643 :                 dummy_execute_data = *EG(current_execute_data);
     734       88643 :                 dummy_execute_data.prev_execute_data = EG(current_execute_data);
     735       88643 :                 dummy_execute_data.call = NULL;
     736       88643 :                 dummy_execute_data.opline = NULL;
     737       88643 :                 dummy_execute_data.func = NULL;
     738       88643 :                 EG(current_execute_data) = &dummy_execute_data;
     739             :         }
     740             : 
     741      705149 :         if (!fci_cache || !fci_cache->initialized) {
     742             :                 zend_string *callable_name;
     743       12386 :                 char *error = NULL;
     744             : 
     745       12386 :                 if (!fci_cache) {
     746       12101 :                         fci_cache = &fci_cache_local;
     747             :                 }
     748             : 
     749       12386 :                 if (!zend_is_callable_ex(&fci->function_name, fci->object, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error)) {
     750          87 :                         if (error) {
     751           0 :                                 zend_error(E_WARNING, "Invalid callback %s, %s", ZSTR_VAL(callable_name), error);
     752           0 :                                 efree(error);
     753             :                         }
     754          87 :                         if (callable_name) {
     755          87 :                                 zend_string_release(callable_name);
     756             :                         }
     757          87 :                         if (EG(current_execute_data) == &dummy_execute_data) {
     758          43 :                                 EG(current_execute_data) = dummy_execute_data.prev_execute_data;
     759             :                         }
     760          87 :                         return FAILURE;
     761       12299 :                 } else if (error) {
     762             :                         /* Capitalize the first latter of the error message */
     763           3 :                         if (error[0] >= 'a' && error[0] <= 'z') {
     764           3 :                                 error[0] += ('A' - 'a');
     765             :                         }
     766           3 :                         zend_error(E_DEPRECATED, "%s", error);
     767           3 :                         efree(error);
     768             :                 }
     769       12299 :                 zend_string_release(callable_name);
     770             :         }
     771             : 
     772      705062 :         func = fci_cache->function_handler;
     773     1410124 :         call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION,
     774             :                 func, fci->param_count, fci_cache->called_scope, fci_cache->object);
     775      705062 :         calling_scope = fci_cache->calling_scope;
     776      705062 :         fci->object = fci_cache->object;
     777     1637424 :         if (fci->object &&
     778      466181 :             (!EG(objects_store).object_buckets ||
     779      466181 :              !IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) {
     780           0 :                 if (EG(current_execute_data) == &dummy_execute_data) {
     781           0 :                         EG(current_execute_data) = dummy_execute_data.prev_execute_data;
     782             :                 }
     783           0 :                 return FAILURE;
     784             :         }
     785             : 
     786      705062 :         if (func->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
     787           0 :                 if (func->common.fn_flags & ZEND_ACC_ABSTRACT) {
     788           0 :                         zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
     789           0 :                         return FAILURE;
     790             :                 }
     791           0 :                 if (func->common.fn_flags & ZEND_ACC_DEPRECATED) {
     792           0 :                         zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
     793           0 :                                 func->common.scope ? ZSTR_VAL(func->common.scope->name) : "",
     794           0 :                                 func->common.scope ? "::" : "",
     795           0 :                                 ZSTR_VAL(func->common.function_name));
     796             :                 }
     797             :         }
     798             : 
     799     1204440 :         for (i=0; i<fci->param_count; i++) {
     800             :                 zval *param;
     801      499382 :                 zval *arg = &fci->params[i];
     802             : 
     803      998764 :                 if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) {
     804         354 :                         if (UNEXPECTED(!Z_ISREF_P(arg))) {
     805         248 :                                 if (fci->no_separation &&
     806           4 :                                         !ARG_MAY_BE_SENT_BY_REF(func, i + 1)) {
     807           4 :                                         if (i) {
     808             :                                                 /* hack to clean up the stack */
     809           0 :                                                 ZEND_CALL_NUM_ARGS(call) = i;
     810             :                                                 zend_vm_stack_free_args(call);
     811             :                                         }
     812             :                                         zend_vm_stack_free_call_frame(call);
     813             : 
     814          14 :                                         zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
     815             :                                                 i+1,
     816           6 :                                                 func->common.scope ? ZSTR_VAL(func->common.scope->name) : "",
     817           4 :                                                 func->common.scope ? "::" : "",
     818           4 :                                                 ZSTR_VAL(func->common.function_name));
     819           4 :                                         if (EG(current_execute_data) == &dummy_execute_data) {
     820           0 :                                                 EG(current_execute_data) = dummy_execute_data.prev_execute_data;
     821             :                                         }
     822           4 :                                         return FAILURE;
     823             :                                 }
     824             : 
     825         240 :                                 ZVAL_NEW_REF(arg, arg);
     826             :                         }
     827             :                         Z_ADDREF_P(arg);
     828             :                 } else {
     829      499110 :                         if (Z_ISREF_P(arg) &&
     830          82 :                             !(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
     831             :                                 /* don't separate references for __call */
     832          82 :                                 arg = Z_REFVAL_P(arg);
     833             :                         }
     834      499028 :                         if (Z_OPT_REFCOUNTED_P(arg)) {
     835             :                                 Z_ADDREF_P(arg);
     836             :                         }
     837             :                 }
     838      499378 :                 param = ZEND_CALL_ARG(call, i+1);
     839      499378 :                 ZVAL_COPY_VALUE(param, arg);
     840             :         }
     841             : 
     842      705058 :         EG(scope) = calling_scope;
     843      705058 :         if (func->common.fn_flags & ZEND_ACC_STATIC) {
     844         399 :                 fci->object = NULL;
     845             :         }
     846      705058 :         Z_OBJ(call->This) = fci->object;
     847             : 
     848      705058 :         if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
     849             :                 ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT);
     850         689 :                 GC_REFCOUNT((zend_object*)func->op_array.prototype)++;
     851         689 :                 ZEND_ADD_CALL_FLAG(call, ZEND_CALL_CLOSURE);
     852             :         }
     853             : 
     854      705058 :         if (func->type == ZEND_USER_FUNCTION) {
     855      459320 :                 int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
     856      459320 :                 EG(scope) = func->common.scope;
     857      459320 :                 call->symbol_table = fci->symbol_table;
     858      459320 :                 if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) {
     859      459317 :                         zend_init_execute_data(call, &func->op_array, fci->retval);
     860      459317 :                         zend_execute_ex(call);
     861             :                 } else {
     862           3 :                         zend_generator_create_zval(call, &func->op_array, fci->retval);
     863             :                 }
     864      459282 :                 if (call_via_handler) {
     865             :                         /* We must re-initialize function again */
     866           7 :                         fci_cache->initialized = 0;
     867             :                 }
     868      245738 :         } else if (func->type == ZEND_INTERNAL_FUNCTION) {
     869      245738 :                 int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0;
     870      245738 :                 ZVAL_NULL(fci->retval);
     871      245738 :                 if (func->common.scope) {
     872      244757 :                         EG(scope) = func->common.scope;
     873             :                 }
     874      245738 :                 call->prev_execute_data = EG(current_execute_data);
     875      245738 :                 call->return_value = NULL; /* this is not a constructor call */
     876      245738 :                 EG(current_execute_data) = call;
     877      245738 :                 if (EXPECTED(zend_execute_internal == NULL)) {
     878             :                         /* saves one function call if zend_execute_internal is not used */
     879      245738 :                         func->internal_function.handler(call, fci->retval);
     880             :                 } else {
     881           0 :                         zend_execute_internal(call, fci->retval);
     882             :                 }
     883      245729 :                 EG(current_execute_data) = call->prev_execute_data;
     884             :                 zend_vm_stack_free_args(call);
     885             : 
     886             :                 /*  We shouldn't fix bad extensions here,
     887             :                         because it can break proper ones (Bug #34045)
     888             :                 if (!EX(function_state).function->common.return_reference)
     889             :                 {
     890             :                         INIT_PZVAL(f->retval);
     891             :                 }*/
     892      245729 :                 if (EG(exception)) {
     893          86 :                         zval_ptr_dtor(fci->retval);
     894          86 :                         ZVAL_UNDEF(fci->retval);
     895             :                 }
     896             : 
     897      245729 :                 if (call_via_handler) {
     898             :                         /* We must re-initialize function again */
     899           4 :                         fci_cache->initialized = 0;
     900             :                 }
     901             :         } else { /* ZEND_OVERLOADED_FUNCTION */
     902           0 :                 ZVAL_NULL(fci->retval);
     903             : 
     904             :                 /* Not sure what should be done here if it's a static method */
     905           0 :                 if (fci->object) {
     906           0 :                         call->prev_execute_data = EG(current_execute_data);
     907           0 :                         EG(current_execute_data) = call;
     908           0 :                         fci->object->handlers->call_method(func->common.function_name, fci->object, call, fci->retval);
     909           0 :                         EG(current_execute_data) = call->prev_execute_data;
     910             :                 } else {
     911           0 :                         zend_throw_error(NULL, "Cannot call overloaded function for non-object");
     912             :                 }
     913             : 
     914             :                 zend_vm_stack_free_args(call);
     915             : 
     916           0 :                 if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
     917           0 :                         zend_string_release(func->common.function_name);
     918             :                 }
     919           0 :                 efree(func);
     920             : 
     921           0 :                 if (EG(exception)) {
     922           0 :                         zval_ptr_dtor(fci->retval);
     923           0 :                         ZVAL_UNDEF(fci->retval);
     924             :                 }
     925             :         }
     926             : 
     927      705011 :         EG(scope) = orig_scope;
     928             :         zend_vm_stack_free_call_frame(call);
     929             : 
     930      705011 :         if (EG(current_execute_data) == &dummy_execute_data) {
     931      108810 :                 EG(current_execute_data) = dummy_execute_data.prev_execute_data;
     932             :         }
     933             : 
     934      705011 :         if (EG(exception)) {
     935         338 :                 zend_throw_exception_internal(NULL);
     936             :         }
     937      705005 :         return SUCCESS;
     938             : }
     939             : /* }}} */
     940             : 
     941      169069 : ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload) /* {{{ */
     942             : {
     943      169069 :         zend_class_entry *ce = NULL;
     944             :         zval args[1];
     945             :         zval local_retval;
     946             :         zend_string *lc_name;
     947             :         zend_fcall_info fcall_info;
     948             :         zend_fcall_info_cache fcall_cache;
     949             : 
     950      169069 :         if (key) {
     951       20626 :                 lc_name = Z_STR_P(key);
     952             :         } else {
     953      148443 :                 if (name == NULL || !ZSTR_LEN(name)) {
     954          84 :                         return NULL;
     955             :                 }
     956             : 
     957      148359 :                 if (ZSTR_VAL(name)[0] == '\\') {
     958          28 :                         lc_name = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
     959          14 :                         zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
     960             :                 } else {
     961      148345 :                         lc_name = zend_string_tolower(name);
     962             :                 }
     963             :         }
     964             : 
     965      337970 :         ce = zend_hash_find_ptr(EG(class_table), lc_name);
     966      168985 :         if (ce) {
     967      168237 :                 if (!key) {
     968             :                         zend_string_release(lc_name);
     969             :                 }
     970      168237 :                 return ce;
     971             :         }
     972             : 
     973             :         /* The compiler is not-reentrant. Make sure we __autoload() only during run-time
     974             :          * (doesn't impact functionality of __autoload()
     975             :         */
     976         748 :         if (!use_autoload || zend_is_compiling()) {
     977         369 :                 if (!key) {
     978             :                         zend_string_release(lc_name);
     979             :                 }
     980         369 :                 return NULL;
     981             :         }
     982             : 
     983         379 :         if (!EG(autoload_func)) {
     984         440 :                 zend_function *func = zend_hash_str_find_ptr(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1);
     985         220 :                 if (func) {
     986          67 :                         EG(autoload_func) = func;
     987             :                 } else {
     988         153 :                         if (!key) {
     989             :                                 zend_string_release(lc_name);
     990             :                         }
     991         153 :                         return NULL;
     992             :                 }
     993             : 
     994             :         }
     995             : 
     996             :         /* Verify class name before passing it to __autoload() */
     997         226 :         if (strspn(ZSTR_VAL(name), "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != ZSTR_LEN(name)) {
     998          11 :                 if (!key) {
     999             :                         zend_string_release(lc_name);
    1000             :                 }
    1001          11 :                 return NULL;
    1002             :         }
    1003             : 
    1004         215 :         if (EG(in_autoload) == NULL) {
    1005          92 :                 ALLOC_HASHTABLE(EG(in_autoload));
    1006          92 :                 zend_hash_init(EG(in_autoload), 8, NULL, NULL, 0);
    1007             :         }
    1008             : 
    1009         215 :         if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) {
    1010           4 :                 if (!key) {
    1011             :                         zend_string_release(lc_name);
    1012             :                 }
    1013           4 :                 return NULL;
    1014             :         }
    1015             : 
    1016         211 :         ZVAL_UNDEF(&local_retval);
    1017             : 
    1018         211 :         if (ZSTR_VAL(name)[0] == '\\') {
    1019           2 :                 ZVAL_STRINGL(&args[0], ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
    1020             :         } else {
    1021         210 :                 ZVAL_STR_COPY(&args[0], name);
    1022             :         }
    1023             : 
    1024         211 :         fcall_info.size = sizeof(fcall_info);
    1025         211 :         fcall_info.function_table = EG(function_table);
    1026         211 :         ZVAL_STR_COPY(&fcall_info.function_name, EG(autoload_func)->common.function_name);
    1027         211 :         fcall_info.symbol_table = NULL;
    1028         211 :         fcall_info.retval = &local_retval;
    1029         211 :         fcall_info.param_count = 1;
    1030         211 :         fcall_info.params = args;
    1031         211 :         fcall_info.object = NULL;
    1032         211 :         fcall_info.no_separation = 1;
    1033             : 
    1034         211 :         fcall_cache.initialized = 1;
    1035         211 :         fcall_cache.function_handler = EG(autoload_func);
    1036         211 :         fcall_cache.calling_scope = NULL;
    1037         211 :         fcall_cache.called_scope = NULL;
    1038         211 :         fcall_cache.object = NULL;
    1039             : 
    1040         211 :         zend_exception_save();
    1041         211 :         if ((zend_call_function(&fcall_info, &fcall_cache) == SUCCESS) && !EG(exception)) {
    1042         362 :                 ce = zend_hash_find_ptr(EG(class_table), lc_name);
    1043             :         }
    1044         207 :         zend_exception_restore();
    1045             : 
    1046         207 :         zval_ptr_dtor(&args[0]);
    1047             :         zval_dtor(&fcall_info.function_name);
    1048             : 
    1049         207 :         zend_hash_del(EG(in_autoload), lc_name);
    1050             : 
    1051         207 :         zval_ptr_dtor(&local_retval);
    1052             : 
    1053         207 :         if (!key) {
    1054             :                 zend_string_release(lc_name);
    1055             :         }
    1056         207 :         return ce;
    1057             : }
    1058             : /* }}} */
    1059             : 
    1060      144960 : ZEND_API zend_class_entry *zend_lookup_class(zend_string *name) /* {{{ */
    1061             : {
    1062      144960 :         return zend_lookup_class_ex(name, NULL, 1);
    1063             : }
    1064             : /* }}} */
    1065             : 
    1066       22675 : ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex) /* {{{ */
    1067             : {
    1068       45677 :         while (ex) {
    1069         794 :                 if (ex->called_scope) {
    1070         277 :                         return ex->called_scope;
    1071         517 :                 } else if (ex->func) {
    1072         480 :                         if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
    1073         190 :                                 return ex->called_scope;
    1074             :                         }
    1075             :                 }
    1076         327 :                 ex = ex->prev_execute_data;
    1077             :         }
    1078       22208 :         return NULL;
    1079             : }
    1080             : /* }}} */
    1081             : 
    1082       22527 : ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex) /* {{{ */
    1083             : {
    1084       45218 :         while (ex) {
    1085         487 :                 if (Z_OBJ(ex->This)) {
    1086          86 :                         return Z_OBJ(ex->This);
    1087         401 :                 } else if (ex->func) {
    1088         400 :                         if (ex->func->type != ZEND_INTERNAL_FUNCTION || ex->func->common.scope) {
    1089         237 :                                 return Z_OBJ(ex->This);
    1090             :                         }
    1091             :                 }
    1092         164 :                 ex = ex->prev_execute_data;
    1093             :         }
    1094       22204 :         return NULL;
    1095             : }
    1096             : /* }}} */
    1097             : 
    1098         171 : ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char *string_name) /* {{{ */
    1099             : {
    1100             :         zval pv;
    1101             :         zend_op_array *new_op_array;
    1102             :         uint32_t original_compiler_options;
    1103             :         int retval;
    1104             : 
    1105         171 :         if (retval_ptr) {
    1106         156 :                 ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 1));
    1107          78 :                 memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
    1108          78 :                 memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len);
    1109          78 :                 Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
    1110          78 :                 Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
    1111             :         } else {
    1112         186 :                 ZVAL_STRINGL(&pv, str, str_len);
    1113             :         }
    1114             : 
    1115             :         /*printf("Evaluating '%s'\n", pv.value.str.val);*/
    1116             : 
    1117         171 :         original_compiler_options = CG(compiler_options);
    1118         171 :         CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
    1119         171 :         new_op_array = zend_compile_string(&pv, string_name);
    1120         171 :         CG(compiler_options) = original_compiler_options;
    1121             : 
    1122         171 :         if (new_op_array) {
    1123             :                 zval local_retval;
    1124             : 
    1125         163 :                 EG(no_extensions)=1;
    1126             : 
    1127         163 :                 zend_try {
    1128         163 :                         ZVAL_UNDEF(&local_retval);
    1129         163 :                         zend_execute(new_op_array, &local_retval);
    1130           1 :                 } zend_catch {
    1131           1 :                         destroy_op_array(new_op_array);
    1132           1 :                         efree_size(new_op_array, sizeof(zend_op_array));
    1133           1 :                         zend_bailout();
    1134         162 :                 } zend_end_try();
    1135             : 
    1136         162 :                 if (Z_TYPE(local_retval) != IS_UNDEF) {
    1137         161 :                         if (retval_ptr) {
    1138          71 :                                 ZVAL_COPY_VALUE(retval_ptr, &local_retval);
    1139             :                         } else {
    1140          90 :                                 zval_ptr_dtor(&local_retval);
    1141             :                         }
    1142             :                 } else {
    1143           1 :                         if (retval_ptr) {
    1144           1 :                                 ZVAL_NULL(retval_ptr);
    1145             :                         }
    1146             :                 }
    1147             : 
    1148         162 :                 EG(no_extensions)=0;
    1149         162 :                 destroy_op_array(new_op_array);
    1150         162 :                 efree_size(new_op_array, sizeof(zend_op_array));
    1151         162 :                 retval = SUCCESS;
    1152             :         } else {
    1153           8 :                 retval = FAILURE;
    1154             :         }
    1155             :         zval_dtor(&pv);
    1156         170 :         return retval;
    1157             : }
    1158             : /* }}} */
    1159             : 
    1160           0 : ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name) /* {{{ */
    1161             : {
    1162           0 :         return zend_eval_stringl(str, strlen(str), retval_ptr, string_name);
    1163             : }
    1164             : /* }}} */
    1165             : 
    1166          25 : ZEND_API int zend_eval_stringl_ex(char *str, size_t str_len, zval *retval_ptr, char *string_name, int handle_exceptions) /* {{{ */
    1167             : {
    1168             :         int result;
    1169             : 
    1170          25 :         result = zend_eval_stringl(str, str_len, retval_ptr, string_name);
    1171          24 :         if (handle_exceptions && EG(exception)) {
    1172           0 :                 zend_exception_error(EG(exception), E_ERROR);
    1173           0 :                 result = FAILURE;
    1174             :         }
    1175          24 :         return result;
    1176             : }
    1177             : /* }}} */
    1178             : 
    1179          25 : ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions) /* {{{ */
    1180             : {
    1181          25 :         return zend_eval_stringl_ex(str, strlen(str), retval_ptr, string_name, handle_exceptions);
    1182             : }
    1183             : /* }}} */
    1184             : 
    1185          13 : ZEND_API void zend_timeout(int dummy) /* {{{ */
    1186             : {
    1187             : 
    1188          13 :         if (zend_on_timeout) {
    1189             : #ifdef ZEND_SIGNALS
    1190             :                 /*
    1191             :                    We got here because we got a timeout signal, so we are in a signal handler
    1192             :                    at this point. However, we want to be able to timeout any user-supplied
    1193             :                    shutdown functions, so pretend we are not in a signal handler while we are
    1194             :                    calling these
    1195             :                 */
    1196             :                 SIGG(running) = 0;
    1197             : #endif
    1198          13 :                 zend_on_timeout(EG(timeout_seconds));
    1199             :         }
    1200             : 
    1201          13 :         zend_error_noreturn(E_ERROR, "Maximum execution time of %pd second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
    1202             : }
    1203             : /* }}} */
    1204             : 
    1205             : #ifdef ZEND_WIN32
    1206             : VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out)
    1207             : {
    1208             :         zend_bool *php_timed_out;
    1209             : 
    1210             :         /* The doc states it'll be always true, however it theoretically
    1211             :                 could be FALSE when the thread was signaled. */
    1212             :         if (!timed_out) {
    1213             :                 return;
    1214             :         }
    1215             : 
    1216             :         php_timed_out = (zend_bool *)arg;
    1217             :         *php_timed_out = 1;
    1218             : }
    1219             : #endif
    1220             : 
    1221             : /* This one doesn't exists on QNX */
    1222             : #ifndef SIGPROF
    1223             : #define SIGPROF 27
    1224             : #endif
    1225             : 
    1226       22609 : void zend_set_timeout(zend_long seconds, int reset_signals) /* {{{ */
    1227             : {
    1228             : 
    1229       22609 :         EG(timeout_seconds) = seconds;
    1230             : 
    1231             : #ifdef ZEND_WIN32
    1232             :         if(!seconds) {
    1233             :                 return;
    1234             :         }
    1235             : 
    1236             :         /* Don't use ChangeTimerQueueTimer() as it will not restart an expired
    1237             :                 timer, so we could end up with just an ignored timeout. Instead
    1238             :                 delete and recreate. */
    1239             :         if (NULL != tq_timer) {
    1240             :                 if (!DeleteTimerQueueTimer(NULL, tq_timer, NULL)) {
    1241             :                         EG(timed_out) = 0;
    1242             :                         tq_timer = NULL;
    1243             :                         zend_error_noreturn(E_ERROR, "Could not delete queued timer");
    1244             :                         return;
    1245             :                 }
    1246             :                 tq_timer = NULL;
    1247             :         }
    1248             : 
    1249             :         /* XXX passing NULL means the default timer queue provided by the system is used */
    1250             :         if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)&EG(timed_out), seconds*1000, 0, WT_EXECUTEONLYONCE)) {
    1251             :                 EG(timed_out) = 0;
    1252             :                 tq_timer = NULL;
    1253             :                 zend_error_noreturn(E_ERROR, "Could not queue new timer");
    1254             :                 return;
    1255             :         }
    1256             :         EG(timed_out) = 0;
    1257             : #else
    1258             : #       ifdef HAVE_SETITIMER
    1259             :         {
    1260             :                 struct itimerval t_r;           /* timeout requested */
    1261             :                 int signo;
    1262             : 
    1263       22609 :                 if(seconds) {
    1264         470 :                         t_r.it_value.tv_sec = seconds;
    1265         470 :                         t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
    1266             : 
    1267             : #       ifdef __CYGWIN__
    1268             :                         setitimer(ITIMER_REAL, &t_r, NULL);
    1269             :                 }
    1270             :                 signo = SIGALRM;
    1271             : #       else
    1272         470 :                         setitimer(ITIMER_PROF, &t_r, NULL);
    1273             :                 }
    1274       22609 :                 signo = SIGPROF;
    1275             : #       endif
    1276             : 
    1277       22609 :                 if (reset_signals) {
    1278             : #       ifdef ZEND_SIGNALS
    1279             :                         zend_signal(signo, zend_timeout);
    1280             : #       else
    1281             :                         sigset_t sigset;
    1282             : 
    1283       22554 :                         signal(signo, zend_timeout);
    1284       22554 :                         sigemptyset(&sigset);
    1285       22554 :                         sigaddset(&sigset, signo);
    1286       22554 :                         sigprocmask(SIG_UNBLOCK, &sigset, NULL);
    1287             : #       endif
    1288             :                 }
    1289             :         }
    1290             : #       endif /* HAVE_SETITIMER */
    1291             : #endif
    1292       22609 : }
    1293             : /* }}} */
    1294             : 
    1295       45213 : void zend_unset_timeout(void) /* {{{ */
    1296             : {
    1297             : #ifdef ZEND_WIN32
    1298             :         if (NULL != tq_timer) {
    1299             :                 if (!DeleteTimerQueueTimer(NULL, tq_timer, NULL)) {
    1300             :                         EG(timed_out) = 0;
    1301             :                         tq_timer = NULL;
    1302             :                         zend_error_noreturn(E_ERROR, "Could not delete queued timer");
    1303             :                         return;
    1304             :                 }
    1305             :                 tq_timer = NULL;
    1306             :         }
    1307             :         EG(timed_out) = 0;
    1308             : #else
    1309             : #       ifdef HAVE_SETITIMER
    1310       45213 :         if (EG(timeout_seconds)) {
    1311             :                 struct itimerval no_timeout;
    1312             : 
    1313         906 :                 no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
    1314             : 
    1315             : #ifdef __CYGWIN__
    1316             :                 setitimer(ITIMER_REAL, &no_timeout, NULL);
    1317             : #else
    1318         906 :                 setitimer(ITIMER_PROF, &no_timeout, NULL);
    1319             : #endif
    1320             :         }
    1321             : #       endif
    1322             : #endif
    1323       45213 : }
    1324             : /* }}} */
    1325             : 
    1326        6105 : zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */
    1327             : {
    1328             :         zend_class_entry *ce;
    1329        6105 :         int fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK;
    1330             : 
    1331             : check_fetch_type:
    1332        6116 :         switch (fetch_sub_type) {
    1333             :                 case ZEND_FETCH_CLASS_SELF:
    1334        1671 :                         if (UNEXPECTED(!EG(scope))) {
    1335           6 :                                 zend_throw_or_error(fetch_type, NULL, "Cannot access self:: when no class scope is active");
    1336             :                         }
    1337        1671 :                         return EG(scope);
    1338             :                 case ZEND_FETCH_CLASS_PARENT:
    1339        1371 :                         if (UNEXPECTED(!EG(scope))) {
    1340           1 :                                 zend_throw_or_error(fetch_type, NULL, "Cannot access parent:: when no class scope is active");
    1341           1 :                                 return NULL;
    1342             :                         }
    1343        1370 :                         if (UNEXPECTED(!EG(scope)->parent)) {
    1344           0 :                                 zend_throw_or_error(fetch_type, NULL, "Cannot access parent:: when current class scope has no parent");
    1345             :                         }
    1346        1370 :                         return EG(scope)->parent;
    1347             :                 case ZEND_FETCH_CLASS_STATIC:
    1348         122 :                         ce = zend_get_called_scope(EG(current_execute_data));
    1349         122 :                         if (UNEXPECTED(!ce)) {
    1350           4 :                                 zend_throw_or_error(fetch_type, NULL, "Cannot access static:: when no class scope is active");
    1351           4 :                                 return NULL;
    1352             :                         }
    1353         118 :                         return ce;
    1354             :                 case ZEND_FETCH_CLASS_AUTO: {
    1355        1481 :                                 fetch_sub_type = zend_get_class_fetch_type(class_name);
    1356        1481 :                                 if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) {
    1357          11 :                                         goto check_fetch_type;
    1358             :                                 }
    1359             :                         }
    1360             :                         break;
    1361             :         }
    1362             : 
    1363        2941 :         if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
    1364        1508 :                 return zend_lookup_class_ex(class_name, NULL, 0);
    1365        1433 :         } else if ((ce = zend_lookup_class_ex(class_name, NULL, 1)) == NULL) {
    1366          16 :                 if (!(fetch_type & ZEND_FETCH_CLASS_SILENT) && !EG(exception)) {
    1367          13 :                         if (fetch_sub_type == ZEND_FETCH_CLASS_INTERFACE) {
    1368           0 :                                 zend_throw_or_error(fetch_type, NULL, "Interface '%s' not found", ZSTR_VAL(class_name));
    1369          13 :                         } else if (fetch_sub_type == ZEND_FETCH_CLASS_TRAIT) {
    1370           0 :                                 zend_throw_or_error(fetch_type, NULL, "Trait '%s' not found", ZSTR_VAL(class_name));
    1371             :                         } else {
    1372          13 :                                 zend_throw_or_error(fetch_type, NULL, "Class '%s' not found", ZSTR_VAL(class_name));
    1373             :                         }
    1374             :                 }
    1375           8 :                 return NULL;
    1376             :         }
    1377        1416 :         return ce;
    1378             : }
    1379             : /* }}} */
    1380             : 
    1381       19244 : zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *key, int fetch_type) /* {{{ */
    1382             : {
    1383             :         zend_class_entry *ce;
    1384             : 
    1385       19244 :         if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) {
    1386        1193 :                 return zend_lookup_class_ex(class_name, key, 0);
    1387       18051 :         } else if ((ce = zend_lookup_class_ex(class_name, key, 1)) == NULL) {
    1388          37 :                 if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) {
    1389          23 :                         if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
    1390           2 :                                 zend_throw_or_error(fetch_type, NULL, "Interface '%s' not found", ZSTR_VAL(class_name));
    1391          21 :                         } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
    1392           2 :                                 zend_throw_or_error(fetch_type, NULL, "Trait '%s' not found", ZSTR_VAL(class_name));
    1393             :                         } else {
    1394          19 :                                 zend_throw_or_error(fetch_type, NULL, "Class '%s' not found", ZSTR_VAL(class_name));
    1395             :                         }
    1396             :                 }
    1397          32 :                 return NULL;
    1398             :         }
    1399       18012 :         return ce;
    1400             : }
    1401             : /* }}} */
    1402             : 
    1403             : #define MAX_ABSTRACT_INFO_CNT 3
    1404             : #define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
    1405             : #define DISPLAY_ABSTRACT_FN(idx) \
    1406             :         ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
    1407             :         ai.afn[idx] ? "::" : "", \
    1408             :         ai.afn[idx] ? ZSTR_VAL(ai.afn[idx]->common.function_name) : "", \
    1409             :         ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
    1410             : 
    1411             : typedef struct _zend_abstract_info {
    1412             :         zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
    1413             :         int cnt;
    1414             :         int ctor;
    1415             : } zend_abstract_info;
    1416             : 
    1417          43 : static void zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai) /* {{{ */
    1418             : {
    1419          43 :         if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    1420          14 :                 if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
    1421          14 :                         ai->afn[ai->cnt] = fn;
    1422             :                 }
    1423          14 :                 if (fn->common.fn_flags & ZEND_ACC_CTOR) {
    1424           1 :                         if (!ai->ctor) {
    1425           1 :                                 ai->cnt++;
    1426           1 :                                 ai->ctor = 1;
    1427             :                         } else {
    1428           0 :                                 ai->afn[ai->cnt] = NULL;
    1429             :                         }
    1430             :                 } else {
    1431          13 :                         ai->cnt++;
    1432             :                 }
    1433             :         }
    1434          43 : }
    1435             : /* }}} */
    1436             : 
    1437     1704166 : void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
    1438             : {
    1439             :         zend_function *func;
    1440             :         zend_abstract_info ai;
    1441             : 
    1442     1704166 :         if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
    1443          23 :                 memset(&ai, 0, sizeof(ai));
    1444             : 
    1445         109 :                 ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
    1446          43 :                         zend_verify_abstract_class_function(func, &ai);
    1447             :                 } ZEND_HASH_FOREACH_END();
    1448             : 
    1449          23 :                 if (ai.cnt) {
    1450         262 :                         zend_error_noreturn(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
    1451          13 :                                 ZSTR_VAL(ce->name), ai.cnt,
    1452          13 :                                 ai.cnt > 1 ? "s" : "",
    1453         103 :                                 DISPLAY_ABSTRACT_FN(0),
    1454          68 :                                 DISPLAY_ABSTRACT_FN(1),
    1455          65 :                                 DISPLAY_ABSTRACT_FN(2)
    1456             :                                 );
    1457             :                 }
    1458             :         }
    1459     1704153 : }
    1460             : /* }}} */
    1461             : 
    1462         465 : ZEND_API int zend_delete_global_variable(zend_string *name) /* {{{ */
    1463             : {
    1464         465 :     return zend_hash_del_ind(&EG(symbol_table), name);
    1465             : }
    1466             : /* }}} */
    1467             : 
    1468       90335 : ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
    1469             : {
    1470             :         zend_execute_data *ex;
    1471             :         zend_array *symbol_table;
    1472             : 
    1473             :         /* Search for last called user function */
    1474       90335 :         ex = EG(current_execute_data);
    1475      182834 :         while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) {
    1476        2164 :                 ex = ex->prev_execute_data;
    1477             :         }
    1478       90335 :         if (!ex) {
    1479          30 :                 return NULL;
    1480             :         }
    1481       90305 :         if (ex->symbol_table) {
    1482        2504 :                 return ex->symbol_table;
    1483             :         }
    1484             : 
    1485       87801 :         if (EG(symtable_cache_ptr) >= EG(symtable_cache)) {
    1486             :                 /*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
    1487       87550 :                 symbol_table = ex->symbol_table = *(EG(symtable_cache_ptr)--);
    1488       87550 :                 if (!ex->func->op_array.last_var) {
    1489           2 :                         return symbol_table;
    1490             :                 }
    1491       87548 :                 zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0);
    1492             :         } else {
    1493         251 :                 symbol_table = ex->symbol_table = emalloc(sizeof(zend_array));
    1494         251 :                 zend_hash_init(symbol_table, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
    1495         251 :                 if (!ex->func->op_array.last_var) {
    1496          13 :                         return symbol_table;
    1497             :                 }
    1498         238 :                 zend_hash_real_init(symbol_table, 0);
    1499             :                 /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
    1500             :         }
    1501       87786 :         if (EXPECTED(ex->func->op_array.last_var)) {
    1502       87786 :                 zend_string **str = ex->func->op_array.vars;
    1503       87786 :                 zend_string **end = str + ex->func->op_array.last_var;
    1504       87786 :                 zval *var = ZEND_CALL_VAR_NUM(ex, 0);
    1505             : 
    1506             :                 do {
    1507      176873 :                         _zend_hash_append_ind(symbol_table, *str, var);
    1508      176873 :                         str++;
    1509      176873 :                         var++;
    1510      176873 :                 } while (str != end);
    1511             :         }
    1512       87786 :         return symbol_table;
    1513             : }
    1514             : /* }}} */
    1515             : 
    1516       43610 : ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */
    1517             : {
    1518       43610 :         zend_op_array *op_array = &execute_data->func->op_array;
    1519       43610 :         HashTable *ht = execute_data->symbol_table;
    1520             : 
    1521             :         /* copy real values from symbol table into CV slots and create
    1522             :            INDIRECT references to CV in symbol table  */
    1523       43610 :         if (EXPECTED(op_array->last_var)) {
    1524       26453 :                 zend_string **str = op_array->vars;
    1525       26453 :                 zend_string **end = str + op_array->last_var;
    1526       26453 :                 zval *var = EX_VAR_NUM(0);
    1527             : 
    1528             :                 do {
    1529      123554 :                         zval *zv = zend_hash_find(ht, *str);
    1530             : 
    1531      123554 :                         if (zv) {
    1532       49403 :                                 if (Z_TYPE_P(zv) == IS_INDIRECT) {
    1533       35506 :                                         zval *val = Z_INDIRECT_P(zv);
    1534             : 
    1535       35506 :                                         ZVAL_COPY_VALUE(var, val);
    1536             :                                 } else {
    1537       13897 :                                         ZVAL_COPY_VALUE(var, zv);
    1538             :                                 }
    1539             :                         } else {
    1540       74151 :                                 ZVAL_UNDEF(var);
    1541       74151 :                                 zv = zend_hash_add_new(ht, *str, var);
    1542             :                         }
    1543      123554 :                         ZVAL_INDIRECT(zv, var);
    1544      123554 :                         str++;
    1545      123554 :                         var++;
    1546      123554 :                 } while (str != end);
    1547             :         }
    1548       43610 : }
    1549             : /* }}} */
    1550             : 
    1551       31533 : ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */
    1552             : {
    1553       31533 :         zend_op_array *op_array = &execute_data->func->op_array;
    1554       31533 :         HashTable *ht = execute_data->symbol_table;
    1555             : 
    1556             :         /* copy real values from CV slots into symbol table */
    1557       31533 :         if (EXPECTED(op_array->last_var)) {
    1558       19083 :                 zend_string **str = op_array->vars;
    1559       19083 :                 zend_string **end = str + op_array->last_var;
    1560       19083 :                 zval *var = EX_VAR_NUM(0);
    1561             : 
    1562             :                 do {
    1563       86719 :                         if (Z_TYPE_P(var) == IS_UNDEF) {
    1564        9036 :                                 zend_hash_del(ht, *str);
    1565             :                         } else {
    1566       77683 :                                 zend_hash_update(ht, *str, var);
    1567       77683 :                                 ZVAL_UNDEF(var);
    1568             :                         }
    1569       86719 :                         str++;
    1570       86719 :                         var++;
    1571       86719 :                 } while (str != end);
    1572             :         }
    1573       31533 : }
    1574             : /* }}} */
    1575             : 
    1576           0 : ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force) /* {{{ */
    1577             : {
    1578           0 :         zend_execute_data *execute_data = EG(current_execute_data);
    1579             : 
    1580           0 :         while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
    1581           0 :                 execute_data = execute_data->prev_execute_data;
    1582             :         }
    1583             : 
    1584           0 :         if (execute_data) {
    1585           0 :                 if (!execute_data->symbol_table) {
    1586           0 :                         zend_ulong h = zend_string_hash_val(name);
    1587           0 :                         zend_op_array *op_array = &execute_data->func->op_array;
    1588             : 
    1589           0 :                         if (EXPECTED(op_array->last_var)) {
    1590           0 :                                 zend_string **str = op_array->vars;
    1591           0 :                                 zend_string **end = str + op_array->last_var;
    1592             : 
    1593             :                                 do {
    1594           0 :                                         if (ZSTR_H(*str) == h &&
    1595           0 :                                             ZSTR_LEN(*str) == ZSTR_LEN(name) &&
    1596           0 :                                             memcmp(ZSTR_VAL(*str), ZSTR_VAL(name), ZSTR_LEN(name)) == 0) {
    1597           0 :                                                 zval *var = EX_VAR_NUM(str - op_array->vars);
    1598           0 :                                                 ZVAL_COPY_VALUE(var, value);
    1599           0 :                                                 return SUCCESS;
    1600             :                                         }
    1601           0 :                                         str++;
    1602           0 :                                 } while (str != end);
    1603             :                         }
    1604           0 :                         if (force) {
    1605           0 :                                 zend_array *symbol_table = zend_rebuild_symbol_table();
    1606           0 :                                 if (symbol_table) {
    1607           0 :                                         return zend_hash_update(symbol_table, name, value) ? SUCCESS : FAILURE;;
    1608             :                                 }
    1609             :                         }
    1610             :                 } else {
    1611           0 :                         return (zend_hash_update_ind(execute_data->symbol_table, name, value) != NULL) ? SUCCESS : FAILURE;
    1612             :                 }
    1613             :         }
    1614           0 :         return FAILURE;
    1615             : }
    1616             : /* }}} */
    1617             : 
    1618       39199 : ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, int force) /* {{{ */
    1619             : {
    1620       39199 :         zend_execute_data *execute_data = EG(current_execute_data);
    1621             : 
    1622      114088 :         while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
    1623       35690 :                 execute_data = execute_data->prev_execute_data;
    1624             :         }
    1625             : 
    1626       39199 :         if (execute_data) {
    1627       39197 :                 if (!execute_data->symbol_table) {
    1628        5811 :                         zend_ulong h = zend_hash_func(name, len);
    1629        5811 :                         zend_op_array *op_array = &execute_data->func->op_array;
    1630        5811 :                         if (EXPECTED(op_array->last_var)) {
    1631        5739 :                                 zend_string **str = op_array->vars;
    1632        5739 :                                 zend_string **end = str + op_array->last_var;
    1633             : 
    1634             :                                 do {
    1635       46311 :                                         if (ZSTR_H(*str) == h &&
    1636           2 :                                             ZSTR_LEN(*str) == len &&
    1637           2 :                                             memcmp(ZSTR_VAL(*str), name, len) == 0) {
    1638           2 :                                                 zval *var = EX_VAR_NUM(str - op_array->vars);
    1639           2 :                                                 zval_ptr_dtor(var);
    1640           2 :                                                 ZVAL_COPY_VALUE(var, value);
    1641           2 :                                                 return SUCCESS;
    1642             :                                         }
    1643       46305 :                                         str++;
    1644       46305 :                                 } while (str != end);
    1645             :                         }
    1646        5809 :                         if (force) {
    1647           0 :                                 zend_array *symbol_table = zend_rebuild_symbol_table();
    1648           0 :                                 if (symbol_table) {
    1649           0 :                                         return zend_hash_str_update(symbol_table, name, len, value) ? SUCCESS : FAILURE;;
    1650             :                                 }
    1651             :                         }
    1652             :                 } else {
    1653       33386 :                         return (zend_hash_str_update_ind(execute_data->symbol_table, name, len, value) != NULL) ? SUCCESS : FAILURE;
    1654             :                 }
    1655             :         }
    1656        5811 :         return FAILURE;
    1657             : }
    1658             : /* }}} */
    1659             : 
    1660             : /*
    1661             :  * Local variables:
    1662             :  * tab-width: 4
    1663             :  * c-basic-offset: 4
    1664             :  * indent-tabs-mode: t
    1665             :  * End:
    1666             :  */

Generated by: LCOV version 1.10

Generated at Sat, 25 Jun 2016 07:08:52 +0000 (43 hours ago)

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