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: 669 807 82.9 %
Date: 2014-07-25 Functions: 38 45 84.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include <stdio.h>
      23             : #include <signal.h>
      24             : 
      25             : #include "zend.h"
      26             : #include "zend_compile.h"
      27             : #include "zend_execute.h"
      28             : #include "zend_API.h"
      29             : #include "zend_ptr_stack.h"
      30             : #include "zend_constants.h"
      31             : #include "zend_extensions.h"
      32             : #include "zend_exceptions.h"
      33             : #include "zend_closures.h"
      34             : #include "zend_vm.h"
      35             : #include "zend_float.h"
      36             : #ifdef HAVE_SYS_TIME_H
      37             : #include <sys/time.h>
      38             : #endif
      39             : 
      40             : ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
      41             : ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
      42             : 
      43             : /* true globals */
      44             : ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 };
      45             : ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL };
      46             : 
      47             : #ifdef ZEND_WIN32
      48             : #include <process.h>
      49             : static WNDCLASS wc;
      50             : static HWND timeout_window;
      51             : static HANDLE timeout_thread_event;
      52             : static HANDLE timeout_thread_handle;
      53             : static DWORD timeout_thread_id;
      54             : static int timeout_thread_initialized=0;
      55             : #endif
      56             : 
      57             : #if 0&&ZEND_DEBUG
      58             : static void (*original_sigsegv_handler)(int);
      59             : static void zend_handle_sigsegv(int dummy) /* {{{ */
      60             : {
      61             :         fflush(stdout);
      62             :         fflush(stderr);
      63             :         if (original_sigsegv_handler == zend_handle_sigsegv) {
      64             :                 signal(SIGSEGV, original_sigsegv_handler);
      65             :         } else {
      66             :                 signal(SIGSEGV, SIG_DFL);
      67             :         }
      68             :         {
      69             :                 TSRMLS_FETCH();
      70             : 
      71             :                 fprintf(stderr, "SIGSEGV caught on opcode %d on opline %d of %s() at %s:%d\n\n",
      72             :                                 active_opline->opcode,
      73             :                                 active_opline-EG(active_op_array)->opcodes,
      74             :                                 get_active_function_name(TSRMLS_C),
      75             :                                 zend_get_executed_filename(TSRMLS_C),
      76             :                                 zend_get_executed_lineno(TSRMLS_C));
      77             : /* See http://support.microsoft.com/kb/190351 */
      78             : #ifdef PHP_WIN32
      79             :                 fflush(stderr);
      80             : #endif
      81             :         }
      82             :         if (original_sigsegv_handler!=zend_handle_sigsegv) {
      83             :                 original_sigsegv_handler(dummy);
      84             :         }
      85             : }
      86             : /* }}} */
      87             : #endif
      88             : 
      89           0 : static void zend_extension_activator(zend_extension *extension TSRMLS_DC) /* {{{ */
      90             : {
      91           0 :         if (extension->activate) {
      92           0 :                 extension->activate();
      93             :         }
      94           0 : }
      95             : /* }}} */
      96             : 
      97           0 : static void zend_extension_deactivator(zend_extension *extension TSRMLS_DC) /* {{{ */
      98             : {
      99           0 :         if (extension->deactivate) {
     100           0 :                 extension->deactivate();
     101             :         }
     102           0 : }
     103             : /* }}} */
     104             : 
     105       44429 : static int clean_non_persistent_function(zend_function *function TSRMLS_DC) /* {{{ */
     106             : {
     107       44429 :         return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
     108             : }
     109             : /* }}} */
     110             : 
     111           0 : static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */
     112             : {
     113           0 :         return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
     114             : }
     115             : /* }}} */
     116             : 
     117       29098 : static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */
     118             : {
     119       29098 :         return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
     120             : }
     121             : /* }}} */
     122             : 
     123           0 : static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */
     124             : {
     125           0 :         return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE;
     126             : }
     127             : /* }}} */
     128             : 
     129       20108 : void init_executor(TSRMLS_D) /* {{{ */
     130             : {
     131       20108 :         zend_init_fpu(TSRMLS_C);
     132             : 
     133       20108 :         INIT_ZVAL(EG(uninitialized_zval));
     134             :         /* trick to make uninitialized_zval never be modified, passed by ref, etc. */
     135             :         Z_ADDREF(EG(uninitialized_zval));
     136       20108 :         INIT_ZVAL(EG(error_zval));
     137       20108 :         EG(uninitialized_zval_ptr)=&EG(uninitialized_zval);
     138       20108 :         EG(error_zval_ptr)=&EG(error_zval);
     139       20108 :         zend_ptr_stack_init(&EG(arg_types_stack));
     140             : /* destroys stack frame, therefore makes core dumps worthless */
     141             : #if 0&&ZEND_DEBUG
     142             :         original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
     143             : #endif
     144       20108 :         EG(return_value_ptr_ptr) = NULL;
     145             : 
     146       20108 :         EG(symtable_cache_ptr) = EG(symtable_cache) - 1;
     147       20108 :         EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1;
     148       20108 :         EG(no_extensions) = 0;
     149             : 
     150       20108 :         EG(function_table) = CG(function_table);
     151       20108 :         EG(class_table) = CG(class_table);
     152             : 
     153       20108 :         EG(in_execution) = 0;
     154       20108 :         EG(in_autoload) = NULL;
     155       20108 :         EG(autoload_func) = NULL;
     156       20108 :         EG(error_handling) = EH_NORMAL;
     157             : 
     158             :         zend_vm_stack_init(TSRMLS_C);
     159             :         zend_vm_stack_push((void *) NULL TSRMLS_CC);
     160             : 
     161       20108 :         zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0);
     162       20108 :         EG(active_symbol_table) = &EG(symbol_table);
     163             : 
     164       20108 :         zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC);
     165       20108 :         EG(opline_ptr) = NULL;
     166             : 
     167       20108 :         zend_hash_init(&EG(included_files), 5, NULL, NULL, 0);
     168             : 
     169       20108 :         EG(ticks_count) = 0;
     170             : 
     171       20108 :         EG(user_error_handler) = NULL;
     172             : 
     173       20108 :         EG(current_execute_data) = NULL;
     174             : 
     175       20108 :         zend_stack_init(&EG(user_error_handlers_error_reporting));
     176       20108 :         zend_ptr_stack_init(&EG(user_error_handlers));
     177       20108 :         zend_ptr_stack_init(&EG(user_exception_handlers));
     178             : 
     179       20108 :         zend_objects_store_init(&EG(objects_store), 1024);
     180             : 
     181       20108 :         EG(full_tables_cleanup) = 0;
     182             : #ifdef ZEND_WIN32
     183             :         EG(timed_out) = 0;
     184             : #endif
     185             : 
     186       20108 :         EG(exception) = NULL;
     187       20108 :         EG(prev_exception) = NULL;
     188             : 
     189       20108 :         EG(scope) = NULL;
     190       20108 :         EG(called_scope) = NULL;
     191             : 
     192       20108 :         EG(This) = NULL;
     193             : 
     194       20108 :         EG(active_op_array) = NULL;
     195             : 
     196       20108 :         EG(active) = 1;
     197       20108 :         EG(start_op) = NULL;
     198       20108 : }
     199             : /* }}} */
     200             : 
     201      266013 : static int zval_call_destructor(zval **zv TSRMLS_DC) /* {{{ */
     202             : {
     203      274839 :         if (Z_TYPE_PP(zv) == IS_OBJECT && Z_REFCOUNT_PP(zv) == 1) {
     204        8183 :                 return ZEND_HASH_APPLY_REMOVE;
     205             :         } else {
     206      257830 :                 return ZEND_HASH_APPLY_KEEP;
     207             :         }
     208             : }
     209             : /* }}} */
     210             : 
     211       20146 : void shutdown_destructors(TSRMLS_D) /* {{{ */
     212             : {
     213       20146 :         zend_try {
     214             :                 int symbols;
     215             :                 do {
     216       24820 :                         symbols = zend_hash_num_elements(&EG(symbol_table));
     217       24820 :                         zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC);
     218       24820 :                 } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
     219       20146 :                 zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);
     220           0 :         } zend_catch {
     221             :                 /* if we couldn't destruct cleanly, mark all objects as destructed anyway */
     222           0 :                 zend_objects_store_mark_destructed(&EG(objects_store) TSRMLS_CC);
     223       20146 :         } zend_end_try();
     224       20146 : }
     225             : /* }}} */
     226             : 
     227       20146 : void shutdown_executor(TSRMLS_D) /* {{{ */
     228             : {
     229       20146 :         zend_try {
     230             : 
     231             : /* Removed because this can not be safely done, e.g. in this situation:
     232             :    Object 1 creates object 2
     233             :    Object 3 holds reference to object 2.
     234             :    Now when 1 and 2 are destroyed, 3 can still access 2 in its destructor, with
     235             :    very problematic results */
     236             : /*              zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC); */
     237             : 
     238             : /* Moved after symbol table cleaners, because  some of the cleaners can call
     239             :    destructors, which would use EG(symtable_cache_ptr) and thus leave leaks */
     240             : /*              while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
     241             :                         zend_hash_destroy(*EG(symtable_cache_ptr));
     242             :                         efree(*EG(symtable_cache_ptr));
     243             :                         EG(symtable_cache_ptr)--;
     244             :                 }
     245             : */
     246       20146 :                 zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC);
     247       20146 :                 zend_hash_graceful_reverse_destroy(&EG(symbol_table));
     248       20146 :         } zend_end_try();
     249             : 
     250       20146 :         zend_try {
     251             :                 zval *zeh;
     252             :                 /* remove error handlers before destroying classes and functions,
     253             :                  * so that if handler used some class, crash would not happen */
     254       20146 :                 if (EG(user_error_handler)) {
     255         242 :                         zeh = EG(user_error_handler);
     256         242 :                         EG(user_error_handler) = NULL;
     257         242 :                         zval_ptr_dtor(&zeh);
     258             :                 }
     259             : 
     260       20146 :                 if (EG(user_exception_handler)) {
     261          11 :                         zeh = EG(user_exception_handler);
     262          11 :                         EG(user_exception_handler) = NULL;
     263          11 :                         zval_ptr_dtor(&zeh);
     264             :                 }
     265             : 
     266       20146 :                 zend_stack_destroy(&EG(user_error_handlers_error_reporting));
     267       20146 :                 zend_stack_init(&EG(user_error_handlers_error_reporting));
     268       20146 :                 zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1);
     269       20146 :                 zend_ptr_stack_clean(&EG(user_exception_handlers), ZVAL_DESTRUCTOR, 1);
     270       20146 :         } zend_end_try();
     271             : 
     272       20146 :         zend_try {
     273             :                 /* Cleanup static data for functions and arrays.
     274             :                  * We need a separate cleanup stage because of the following problem:
     275             :                  * Suppose we destroy class X, which destroys the class's function table,
     276             :                  * and in the function table we have function foo() that has static $bar.
     277             :                  * Now if an object of class X is assigned to $bar, its destructor will be
     278             :                  * called and will fail since X's function table is in mid-destruction.
     279             :                  * So we want first of all to clean up all data and then move to tables destruction.
     280             :                  * Note that only run-time accessed data need to be cleaned up, pre-defined data can
     281             :                  * not contain objects and thus are not probelmatic */
     282       20146 :                 if (EG(full_tables_cleanup)) {
     283           0 :                         zend_hash_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
     284           0 :                         zend_hash_apply(EG(class_table), (apply_func_t) zend_cleanup_class_data TSRMLS_CC);
     285             :                 } else {
     286       20146 :                         zend_hash_reverse_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
     287       20146 :                         zend_hash_reverse_apply(EG(class_table), (apply_func_t) zend_cleanup_user_class_data TSRMLS_CC);
     288       20145 :                         zend_cleanup_internal_classes(TSRMLS_C);
     289             :                 }
     290       20146 :         } zend_end_try();
     291             : 
     292       20146 :         zend_try {
     293             :                 zend_vm_stack_destroy(TSRMLS_C);
     294             : 
     295       20146 :                 zend_objects_store_free_object_storage(&EG(objects_store) TSRMLS_CC);
     296             : 
     297             :                 /* Destroy all op arrays */
     298       20146 :                 if (EG(full_tables_cleanup)) {
     299           0 :                         zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
     300           0 :                         zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class_full TSRMLS_CC);
     301             :                 } else {
     302       20146 :                         zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function TSRMLS_CC);
     303       20146 :                         zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class TSRMLS_CC);
     304             :                 }
     305             : 
     306       40922 :                 while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
     307         630 :                         zend_hash_destroy(*EG(symtable_cache_ptr));
     308         630 :                         FREE_HASHTABLE(*EG(symtable_cache_ptr));
     309         630 :                         EG(symtable_cache_ptr)--;
     310             :                 }
     311       20146 :         } zend_end_try();
     312             : 
     313       20146 :         zend_try {
     314       20146 :                 clean_non_persistent_constants(TSRMLS_C);
     315       20146 :         } zend_end_try();
     316             : 
     317       20146 :         zend_try {
     318             : #if 0&&ZEND_DEBUG
     319             :         signal(SIGSEGV, original_sigsegv_handler);
     320             : #endif
     321             : 
     322       20146 :                 zend_hash_destroy(&EG(included_files));
     323             : 
     324       20146 :                 zend_ptr_stack_destroy(&EG(arg_types_stack));
     325       20146 :                 zend_stack_destroy(&EG(user_error_handlers_error_reporting));
     326       20146 :                 zend_ptr_stack_destroy(&EG(user_error_handlers));
     327       20146 :                 zend_ptr_stack_destroy(&EG(user_exception_handlers));
     328       20146 :                 zend_objects_store_destroy(&EG(objects_store));
     329       20146 :                 if (EG(in_autoload)) {
     330         160 :                         zend_hash_destroy(EG(in_autoload));
     331         160 :                         FREE_HASHTABLE(EG(in_autoload));
     332             :                 }
     333       20146 :         } zend_end_try();
     334             : 
     335       20146 :         zend_shutdown_fpu(TSRMLS_C);
     336             : 
     337       20146 :         EG(active) = 0;
     338       20146 : }
     339             : /* }}} */
     340             : 
     341             : /* return class name and "::" or "". */
     342      200057 : ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ */
     343             : {
     344      200057 :         if (!zend_is_executing(TSRMLS_C)) {
     345           0 :                 if (space) {
     346           0 :                         *space = "";
     347             :                 }
     348           0 :                 return "";
     349             :         }
     350      200057 :         switch (EG(current_execute_data)->function_state.function->type) {
     351             :                 case ZEND_USER_FUNCTION:
     352             :                 case ZEND_INTERNAL_FUNCTION:
     353             :                 {
     354      200057 :                         zend_class_entry *ce = EG(current_execute_data)->function_state.function->common.scope;
     355             : 
     356      200057 :                         if (space) {
     357      200057 :                                 *space = ce ? "::" : "";
     358             :                         }
     359      200057 :                         return ce ? ce->name : "";
     360             :                 }
     361             :                 default:
     362           0 :                         if (space) {
     363           0 :                                 *space = "";
     364             :                         }
     365           0 :                         return "";
     366             :         }
     367             : }
     368             : /* }}} */
     369             : 
     370      200144 : ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */
     371             : {
     372      200144 :         if (!zend_is_executing(TSRMLS_C)) {
     373          13 :                 return NULL;
     374             :         }
     375      200131 :         switch (EG(current_execute_data)->function_state.function->type) {
     376             :                 case ZEND_USER_FUNCTION: {
     377         273 :                                 const char *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name;
     378             : 
     379         273 :                                 if (function_name) {
     380         219 :                                         return function_name;
     381             :                                 } else {
     382          54 :                                         return "main";
     383             :                                 }
     384             :                         }
     385             :                         break;
     386             :                 case ZEND_INTERNAL_FUNCTION:
     387      199858 :                         return ((zend_internal_function *) EG(current_execute_data)->function_state.function)->function_name;
     388             :                         break;
     389             :                 default:
     390           0 :                         return NULL;
     391             :         }
     392             : }
     393             : /* }}} */
     394             : 
     395      345104 : ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */
     396             : {
     397      345104 :         if (EG(active_op_array)) {
     398      345099 :                 return EG(active_op_array)->filename;
     399             :         } else {
     400           5 :                 return "[no active file]";
     401             :         }
     402             : }
     403             : /* }}} */
     404             : 
     405      338004 : ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
     406             : {
     407      338106 :         if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION && 
     408         102 :                 active_opline->lineno == 0 && EG(opline_before_exception)) {
     409          51 :                 return EG(opline_before_exception)->lineno;
     410             :         }
     411      337953 :         if (EG(opline_ptr)) {
     412      337948 :                 return active_opline->lineno;
     413             :         } else {
     414           5 :                 return 0;
     415             :         }
     416             : }
     417             : /* }}} */
     418             : 
     419      767085 : ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */
     420             : {
     421      767085 :         return EG(in_execution);
     422             : }
     423             : /* }}} */
     424             : 
     425    18431145 : ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
     426             : {
     427             : #if DEBUG_ZEND>=2
     428             :         printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
     429             : #endif
     430    18431145 :         Z_DELREF_PP(zval_ptr);
     431    36862290 :         if (Z_REFCOUNT_PP(zval_ptr) == 0) {
     432             :                 TSRMLS_FETCH();
     433             : 
     434     8727641 :                 if (*zval_ptr != &EG(uninitialized_zval)) {
     435     8727641 :                         GC_REMOVE_ZVAL_FROM_BUFFER(*zval_ptr);
     436     8727641 :                         zval_dtor(*zval_ptr);
     437     8727636 :                         efree_rel(*zval_ptr);
     438             :                 }
     439             :         } else {
     440             :                 TSRMLS_FETCH();
     441             : 
     442    19407008 :                 if (Z_REFCOUNT_PP(zval_ptr) == 1) {
     443     4691200 :                         Z_UNSET_ISREF_PP(zval_ptr);
     444             :                 }
     445             : 
     446     9703504 :                 GC_ZVAL_CHECK_POSSIBLE_ROOT(*zval_ptr);
     447             :         }
     448    18431140 : }
     449             : /* }}} */
     450             : 
     451    14474079 : ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
     452             : {
     453             : #if DEBUG_ZEND>=2
     454             :         printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
     455             : #endif
     456    14474079 :         Z_DELREF_PP(zval_ptr);
     457    28948158 :         if (Z_REFCOUNT_PP(zval_ptr) == 0) {
     458     9911817 :                 zval_internal_dtor(*zval_ptr);
     459     9911817 :                 free(*zval_ptr);
     460     9124524 :         } else if (Z_REFCOUNT_PP(zval_ptr) == 1) {
     461      968976 :                 Z_UNSET_ISREF_PP(zval_ptr);
     462             :         }
     463    14474079 : }
     464             : /* }}} */
     465             : 
     466       10151 : ZEND_API int zend_is_true(zval *op) /* {{{ */
     467             : {
     468       10151 :         return i_zend_is_true(op);
     469             : }
     470             : /* }}} */
     471             : 
     472             : #include "../TSRM/tsrm_strtok_r.h"
     473             : 
     474             : #define IS_VISITED_CONSTANT                     IS_CONSTANT_INDEX
     475             : #define IS_CONSTANT_VISITED(p)          (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
     476             : #define Z_REAL_TYPE_P(p)                        (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT)
     477             : #define MARK_CONSTANT_VISITED(p)        Z_TYPE_P(p) |= IS_VISITED_CONSTANT
     478             : 
     479          31 : static void zval_deep_copy(zval **p)
     480             : {
     481             :         zval *value;
     482             : 
     483          31 :         ALLOC_ZVAL(value);
     484          31 :         *value = **p;
     485          31 :         Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX;
     486             :         zval_copy_ctor(value);
     487          31 :         Z_TYPE_P(value) = Z_TYPE_PP(p);
     488          31 :         INIT_PZVAL(value);
     489          31 :         *p = value;
     490          31 : }
     491             : 
     492      132692 : ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */
     493             : {
     494      132692 :         zval *p = *pp;
     495      132692 :         zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg;
     496             :         zval const_value;
     497             :         char *colon;
     498             : 
     499      132692 :         if (IS_CONSTANT_VISITED(p)) {
     500           1 :                 zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
     501      132691 :         } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
     502             :                 int refcount;
     503             :                 zend_uchar is_ref;
     504             : 
     505         571 :                 SEPARATE_ZVAL_IF_NOT_REF(pp);
     506         211 :                 p = *pp;
     507             : 
     508         211 :                 MARK_CONSTANT_VISITED(p);
     509             : 
     510         211 :                 refcount = Z_REFCOUNT_P(p);
     511         211 :                 is_ref = Z_ISREF_P(p);
     512             : 
     513         211 :                 if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) {
     514          14 :                         char *actual = Z_STRVAL_P(p);
     515             : 
     516          14 :                         if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
     517           0 :                                 zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p));
     518           0 :                                 Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1);
     519           0 :                                 if (inline_change) {
     520           0 :                                         colon = estrndup(colon, Z_STRLEN_P(p));
     521           0 :                                         str_efree(Z_STRVAL_P(p));
     522           0 :                                         Z_STRVAL_P(p) = colon;
     523             :                                 } else {
     524           0 :                                         Z_STRVAL_P(p) = colon + 1;
     525             :                                 }
     526             :                         } else {
     527          14 :                                 char *save = actual, *slash;
     528          14 :                                 int actual_len = Z_STRLEN_P(p);
     529          14 :                                 if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) {
     530           2 :                                         actual = slash + 1;
     531           2 :                                         actual_len -= (actual - Z_STRVAL_P(p));
     532           2 :                                         if (inline_change) {
     533           1 :                                                 actual = estrndup(actual, actual_len);
     534           1 :                                                 Z_STRVAL_P(p) = actual;
     535           1 :                                                 Z_STRLEN_P(p) = actual_len;
     536             :                                         }
     537             :                                 }
     538          14 :                                 if (actual[0] == '\\') {
     539           0 :                                         if (inline_change) {
     540           0 :                                                 memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p));
     541           0 :                                                 --Z_STRLEN_P(p);
     542             :                                         } else {
     543           0 :                                                 ++actual;
     544             :                                         }
     545           0 :                                         --actual_len;
     546             :                                 }
     547          14 :                                 if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
     548          10 :                                         int fix_save = 0;
     549          10 :                                         if (save[0] == '\\') {
     550           0 :                                                 save++;
     551           0 :                                                 fix_save = 1;
     552             :                                         }
     553          10 :                                         zend_error(E_ERROR, "Undefined constant '%s'", save);
     554           0 :                                         if (fix_save) {
     555           0 :                                                 save--;
     556             :                                         }
     557           0 :                                         if (inline_change && !IS_INTERNED(save)) {
     558           0 :                                                 efree(save);
     559             :                                         }
     560           0 :                                         save = NULL;
     561             :                                 }
     562           4 :                                 if (inline_change && save && save != actual && !IS_INTERNED(save)) {
     563           1 :                                         efree(save);
     564             :                                 }
     565           4 :                                 zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",  actual,  actual);
     566           4 :                                 p->type = IS_STRING;
     567           4 :                                 if (!inline_change) {
     568           1 :                                         Z_STRVAL_P(p) = actual;
     569           1 :                                         Z_STRLEN_P(p) = actual_len;
     570             :                                         zval_copy_ctor(p);
     571             :                                 }
     572             :                         }
     573             :                 } else {
     574         189 :                         if (inline_change) {
     575         104 :                                 STR_FREE(Z_STRVAL_P(p));
     576             :                         }
     577         189 :                         *p = const_value;
     578             :                 }
     579             : 
     580         193 :                 Z_SET_REFCOUNT_P(p, refcount);
     581         193 :                 Z_SET_ISREF_TO_P(p, is_ref);
     582      132480 :         } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) {
     583             :                 zval **element, *new_val;
     584             :                 char *str_index;
     585             :                 uint str_index_len;
     586             :                 ulong num_index;
     587             :                 int ret;
     588             : 
     589        3260 :                 SEPARATE_ZVAL_IF_NOT_REF(pp);
     590        1102 :                 p = *pp;
     591        1102 :                 Z_TYPE_P(p) = IS_ARRAY;
     592             : 
     593        1102 :                 if (!inline_change) {
     594             :                         zval *tmp;
     595          54 :                         HashTable *tmp_ht = NULL;
     596             : 
     597          54 :                         ALLOC_HASHTABLE(tmp_ht);
     598          54 :                         zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0);
     599          54 :                         zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *));
     600          54 :                         Z_ARRVAL_P(p) = tmp_ht;
     601             :                 } 
     602             : 
     603             :                 /* First go over the array and see if there are any constant indices */
     604        1102 :                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
     605        5016 :                 while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) {
     606        2818 :                         if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) {
     607        2732 :                                 zend_hash_move_forward(Z_ARRVAL_P(p));
     608        2732 :                                 continue;
     609             :                         }
     610          86 :                         Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX;
     611          86 :                         if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) {
     612           0 :                                 zend_hash_move_forward(Z_ARRVAL_P(p));
     613           0 :                                 continue;
     614             :                         }
     615          86 :                         if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) {
     616             :                                 char *actual;
     617           7 :                                 const char *save = str_index;
     618           7 :                                 if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) {
     619           0 :                                         zend_error(E_ERROR, "Undefined class constant '%s'", str_index);
     620           0 :                                         str_index_len -= ((colon - str_index) + 1);
     621           0 :                                         str_index = colon;
     622             :                                 } else {
     623           7 :                                         if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) {
     624           2 :                                                 if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) {
     625           1 :                                                         actual++;
     626           1 :                                                         str_index_len -= (actual - str_index);
     627           1 :                                                         str_index = actual;
     628             :                                                 }
     629             :                                         }
     630           7 :                                         if (str_index[0] == '\\') {
     631           0 :                                                 ++str_index;
     632           0 :                                                 --str_index_len;
     633             :                                         }
     634           7 :                                         if (save[0] == '\\') {
     635           0 :                                                 ++save;
     636             :                                         }
     637           7 :                                         if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) {
     638           5 :                                                 zend_error(E_ERROR, "Undefined constant '%s'", save);
     639             :                                         }
     640           2 :                                         zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",   str_index, str_index);
     641             :                                 }
     642           2 :                                 ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1);
     643             :                         }
     644             : 
     645         160 :                         if (Z_REFCOUNT_PP(element) > 1) {
     646           3 :                                 ALLOC_ZVAL(new_val);
     647           3 :                                 *new_val = **element;
     648             :                                 zval_copy_ctor(new_val);
     649             :                                 Z_SET_REFCOUNT_P(new_val, 1);
     650             :                                 Z_UNSET_ISREF_P(new_val);
     651             : 
     652             :                                 /* preserve this bit for inheritance */
     653           3 :                                 Z_TYPE_PP(element) |= IS_CONSTANT_INDEX;
     654           3 :                                 zval_ptr_dtor(element);
     655           3 :                                 *element = new_val;
     656             :                         }
     657             : 
     658          80 :                         switch (Z_TYPE(const_value)) {
     659             :                                 case IS_STRING:
     660          27 :                                         ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE);
     661          27 :                                         break;
     662             :                                 case IS_BOOL:
     663             :                                 case IS_LONG:
     664          53 :                                         ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL);
     665          53 :                                         break;
     666             :                                 case IS_DOUBLE:
     667           0 :                                         ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL);
     668           0 :                                         break;
     669             :                                 case IS_NULL:
     670           0 :                                         ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL);
     671           0 :                                         break;
     672             :                                 default:
     673           0 :                                         ret = SUCCESS;
     674             :                                         break;
     675             :                         }
     676          80 :                         if (ret == SUCCESS) {
     677          78 :                                 zend_hash_move_forward(Z_ARRVAL_P(p));
     678             :                         }
     679             :                         zval_dtor(&const_value);
     680             :                 }
     681        1096 :                 zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC);
     682        1087 :                 zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
     683             :         }
     684      132658 :         return 0;
     685             : }
     686             : /* }}} */
     687             : 
     688        2987 : ZEND_API int zval_update_constant_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */
     689             : {
     690        2987 :         return zval_update_constant_ex(pp, (void*)1, scope TSRMLS_CC);
     691             : }
     692             : /* }}} */
     693             : 
     694           0 : ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */
     695             : {
     696           0 :         return zval_update_constant_ex(pp, (void*)0, scope TSRMLS_CC);
     697             : }
     698             : /* }}} */
     699             : 
     700      129413 : ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) /* {{{ */
     701             : {
     702      129413 :         return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC);
     703             : }
     704             : /* }}} */
     705             : 
     706        1340 : int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC) /* {{{ */
     707             : {
     708             :         zval ***params_array;
     709             :         zend_uint i;
     710             :         int ex_retval;
     711        1340 :         zval *local_retval_ptr = NULL;
     712             : 
     713        1340 :         if (param_count) {
     714        1073 :                 params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
     715        3989 :                 for (i=0; i<param_count; i++) {
     716        2916 :                         params_array[i] = &params[i];
     717             :                 }
     718             :         } else {
     719         267 :                 params_array = NULL;
     720             :         }
     721        1340 :         ex_retval = call_user_function_ex(function_table, object_pp, function_name, &local_retval_ptr, param_count, params_array, 1, NULL TSRMLS_CC);
     722        1313 :         if (local_retval_ptr) {
     723        3891 :                 COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
     724             :         } else {
     725          16 :                 INIT_ZVAL(*retval_ptr);
     726             :         }
     727        1313 :         if (params_array) {
     728        1054 :                 efree(params_array);
     729             :         }
     730        1313 :         return ex_retval;
     731             : }
     732             : /* }}} */
     733             : 
     734       11580 : int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC) /* {{{ */
     735             : {
     736             :         zend_fcall_info fci;
     737             : 
     738       11580 :         fci.size = sizeof(fci);
     739       11580 :         fci.function_table = function_table;
     740       11580 :         fci.object_ptr = object_pp ? *object_pp : NULL;
     741       11580 :         fci.function_name = function_name;
     742       11580 :         fci.retval_ptr_ptr = retval_ptr_ptr;
     743       11580 :         fci.param_count = param_count;
     744       11580 :         fci.params = params;
     745       11580 :         fci.no_separation = (zend_bool) no_separation;
     746       11580 :         fci.symbol_table = symbol_table;
     747             : 
     748       11580 :         return zend_call_function(&fci, NULL TSRMLS_CC);
     749             : }
     750             : /* }}} */
     751             : 
     752      594029 : int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */
     753             : {
     754             :         zend_uint i;
     755             :         zval **original_return_value;
     756             :         HashTable *calling_symbol_table;
     757             :         zend_op_array *original_op_array;
     758             :         zend_op **original_opline_ptr;
     759             :         zend_class_entry *current_scope;
     760             :         zend_class_entry *current_called_scope;
     761      594029 :         zend_class_entry *calling_scope = NULL;
     762      594029 :         zend_class_entry *called_scope = NULL;
     763             :         zval *current_this;
     764             :         zend_execute_data execute_data;
     765             :         zend_fcall_info_cache fci_cache_local;
     766             : 
     767      594029 :         *fci->retval_ptr_ptr = NULL;
     768             : 
     769      594029 :         if (!EG(active)) {
     770           3 :                 return FAILURE; /* executor is already inactive */
     771             :         }
     772             : 
     773      594026 :         if (EG(exception)) {
     774           9 :                 return FAILURE; /* we would result in an instable executor otherwise */
     775             :         }
     776             : 
     777      594017 :         switch (fci->size) {
     778             :                 case sizeof(zend_fcall_info):
     779      594017 :                         break; /* nothing to do currently */
     780             :                 default:
     781           0 :                         zend_error(E_ERROR, "Corrupted fcall_info provided to zend_call_function()");
     782             :                         break;
     783             :         }
     784             : 
     785             :         /* Initialize execute_data */
     786      594017 :         if (EG(current_execute_data)) {
     787      578938 :                 execute_data = *EG(current_execute_data);
     788      578938 :                 EX(op_array) = NULL;
     789      578938 :                 EX(opline) = NULL;
     790      578938 :                 EX(object) = NULL;
     791             :         } else {
     792             :                 /* This only happens when we're called outside any execute()'s
     793             :                  * It shouldn't be strictly necessary to NULL execute_data out,
     794             :                  * but it may make bugs easier to spot
     795             :                  */
     796       15079 :                 memset(&execute_data, 0, sizeof(zend_execute_data));
     797             :         }
     798             : 
     799      594017 :         if (!fci_cache || !fci_cache->initialized) {
     800             :                 char *callable_name;
     801      239015 :                 char *error = NULL;
     802             : 
     803      239015 :                 if (!fci_cache) {
     804       11964 :                         fci_cache = &fci_cache_local;
     805             :                 }
     806             : 
     807      239015 :                 if (!zend_is_callable_ex(fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) {
     808         254 :                         if (error) {
     809           0 :                                 zend_error(E_WARNING, "Invalid callback %s, %s", callable_name, error);
     810           0 :                                 efree(error);
     811             :                         }
     812         254 :                         if (callable_name) {
     813         252 :                                 efree(callable_name);
     814             :                         }
     815         254 :                         return FAILURE;
     816      238761 :                 } else if (error) {
     817             :                         /* Capitalize the first latter of the error message */
     818           3 :                         if (error[0] >= 'a' && error[0] <= 'z') {
     819           3 :                                 error[0] += ('A' - 'a');
     820             :                         }
     821           3 :                         zend_error(E_STRICT, "%s", error);
     822           3 :                         efree(error);
     823             :                 }
     824      238761 :                 efree(callable_name);
     825             :         }
     826             : 
     827      593763 :         EX(function_state).function = fci_cache->function_handler;
     828      593763 :         calling_scope = fci_cache->calling_scope;
     829      593763 :         called_scope = fci_cache->called_scope;
     830      593763 :         fci->object_ptr = fci_cache->object_ptr;
     831      593763 :         EX(object) = fci->object_ptr;
     832     1318871 :         if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT &&
     833      725108 :             (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) {
     834           0 :                 return FAILURE;
     835             :         }
     836             : 
     837      593763 :         if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
     838           1 :                 if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
     839           1 :                         zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
     840             :                 }
     841           0 :                 if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
     842           0 :                         zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
     843           0 :                                 EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
     844           0 :                                 EX(function_state).function->common.scope ? "::" : "",
     845           0 :                                 EX(function_state).function->common.function_name);
     846             :                 }
     847             :         }
     848             : 
     849      593762 :         ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1);
     850             : 
     851     1146404 :         for (i=0; i<fci->param_count; i++) {
     852             :                 zval *param;
     853             : 
     854      619450 :                 if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
     855      133839 :                         if (!PZVAL_IS_REF(*fci->params[i]) && Z_REFCOUNT_PP(fci->params[i]) > 1) {
     856             :                                 zval *new_zval;
     857             : 
     858          58 :                                 if (fci->no_separation &&
     859          36 :                                     !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
     860           8 :                                         if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) {
     861             :                                                 /* hack to clean up the stack */
     862           1 :                                                 zend_vm_stack_push_nocheck((void *) (zend_uintptr_t)i TSRMLS_CC);
     863             :                                                 zend_vm_stack_clear_multiple(TSRMLS_C);
     864             :                                         }
     865             : 
     866          26 :                                         zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
     867             :                                                 i+1,
     868          10 :                                                 EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
     869           8 :                                                 EX(function_state).function->common.scope ? "::" : "",
     870           8 :                                                 EX(function_state).function->common.function_name);
     871           8 :                                         return FAILURE;
     872             :                                 }
     873             : 
     874          14 :                                 ALLOC_ZVAL(new_zval);
     875          14 :                                 *new_zval = **fci->params[i];
     876             :                                 zval_copy_ctor(new_zval);
     877             :                                 Z_SET_REFCOUNT_P(new_zval, 1);
     878          14 :                                 Z_DELREF_PP(fci->params[i]);
     879          14 :                                 *fci->params[i] = new_zval;
     880             :                         }
     881       66800 :                         Z_ADDREF_PP(fci->params[i]);
     882       66800 :                         Z_SET_ISREF_PP(fci->params[i]);
     883       66800 :                         param = *fci->params[i];
     884      972028 :                 } else if (PZVAL_IS_REF(*fci->params[i]) &&
     885             :                            /* don't separate references for __call */
     886         173 :                            (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) {
     887         171 :                         ALLOC_ZVAL(param);
     888         171 :                         *param = **(fci->params[i]);
     889         171 :                         INIT_PZVAL(param);
     890             :                         zval_copy_ctor(param);
     891      485671 :                 } else if (*fci->params[i] != &EG(uninitialized_zval)) {
     892      485665 :                         Z_ADDREF_PP(fci->params[i]);
     893      485665 :                         param = *fci->params[i];
     894             :                 } else {
     895           6 :                         ALLOC_ZVAL(param);
     896           6 :                         *param = **(fci->params[i]);
     897           6 :                         INIT_PZVAL(param);
     898             :                 }
     899             :                 zend_vm_stack_push_nocheck(param TSRMLS_CC);
     900             :         }
     901             : 
     902      593754 :         EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
     903      593754 :         zend_vm_stack_push_nocheck((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC);
     904             : 
     905      593754 :         current_scope = EG(scope);
     906      593754 :         EG(scope) = calling_scope;
     907             : 
     908      593754 :         current_this = EG(This);
     909             : 
     910      593754 :         current_called_scope = EG(called_scope);
     911      593754 :         if (called_scope) {
     912      363055 :                 EG(called_scope) = called_scope;
     913      230699 :         } else if (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION) {
     914      229647 :                 EG(called_scope) = NULL;
     915             :         }
     916             : 
     917      593754 :         if (fci->object_ptr) {
     918      362551 :                 if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
     919          42 :                         EG(This) = NULL;
     920             :                 } else {
     921      362509 :                         EG(This) = fci->object_ptr;
     922             : 
     923      725018 :                         if (!PZVAL_IS_REF(EG(This))) {
     924      348978 :                                 Z_ADDREF_P(EG(This)); /* For $this pointer */
     925             :                         } else {
     926             :                                 zval *this_ptr;
     927             : 
     928       13531 :                                 ALLOC_ZVAL(this_ptr);
     929       13531 :                                 *this_ptr = *EG(This);
     930       13531 :                                 INIT_PZVAL(this_ptr);
     931             :                                 zval_copy_ctor(this_ptr);
     932       13531 :                                 EG(This) = this_ptr;
     933             :                         }
     934             :                 }
     935             :         } else {
     936      231203 :                 EG(This) = NULL;
     937             :         }
     938             : 
     939      593754 :         EX(prev_execute_data) = EG(current_execute_data);
     940      593754 :         EG(current_execute_data) = &execute_data;
     941             : 
     942      593754 :         if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
     943      451068 :                 calling_symbol_table = EG(active_symbol_table);
     944      451068 :                 EG(scope) = EX(function_state).function->common.scope;
     945      451068 :                 if (fci->symbol_table) {
     946           0 :                         EG(active_symbol_table) = fci->symbol_table;
     947             :                 } else {
     948      451068 :                         EG(active_symbol_table) = NULL;
     949             :                 }
     950             : 
     951      451068 :                 original_return_value = EG(return_value_ptr_ptr);
     952      451068 :                 original_op_array = EG(active_op_array);
     953      451068 :                 EG(return_value_ptr_ptr) = fci->retval_ptr_ptr;
     954      451068 :                 EG(active_op_array) = (zend_op_array *) EX(function_state).function;
     955      451068 :                 original_opline_ptr = EG(opline_ptr);
     956      451068 :                 zend_execute(EG(active_op_array) TSRMLS_CC);
     957      451023 :                 if (!fci->symbol_table && EG(active_symbol_table)) {
     958         234 :                         if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
     959           0 :                                 zend_hash_destroy(EG(active_symbol_table));
     960           0 :                                 FREE_HASHTABLE(EG(active_symbol_table));
     961             :                         } else {
     962             :                                 /* clean before putting into the cache, since clean
     963             :                                    could call dtors, which could use cached hash */
     964         234 :                                 zend_hash_clean(EG(active_symbol_table));
     965         234 :                                 *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
     966             :                         }
     967             :                 }
     968      451023 :                 EG(active_symbol_table) = calling_symbol_table;
     969      451023 :                 EG(active_op_array) = original_op_array;
     970      451023 :                 EG(return_value_ptr_ptr)=original_return_value;
     971      451023 :                 EG(opline_ptr) = original_opline_ptr;
     972      142686 :         } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
     973      142686 :                 int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
     974      142686 :                 ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
     975      142686 :                 if (EX(function_state).function->common.scope) {
     976      141634 :                         EG(scope) = EX(function_state).function->common.scope;
     977             :                 }
     978      142686 :                 ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
     979             :                 /*  We shouldn't fix bad extensions here,
     980             :                         because it can break proper ones (Bug #34045)
     981             :                 if (!EX(function_state).function->common.return_reference)
     982             :                 {
     983             :                         INIT_PZVAL(*fci->retval_ptr_ptr);
     984             :                 }*/
     985      142669 :                 if (EG(exception) && fci->retval_ptr_ptr) {
     986          74 :                         zval_ptr_dtor(fci->retval_ptr_ptr);
     987          74 :                         *fci->retval_ptr_ptr = NULL;
     988             :                 }
     989             : 
     990      142669 :                 if (call_via_handler) {
     991             :                         /* We must re-initialize function again */
     992          41 :                         fci_cache->initialized = 0;
     993             :                 }
     994             :         } else { /* ZEND_OVERLOADED_FUNCTION */
     995           0 :                 ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
     996             : 
     997             :                 /* Not sure what should be done here if it's a static method */
     998           0 :                 if (fci->object_ptr) {
     999           0 :                         Z_OBJ_HT_P(fci->object_ptr)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
    1000             :                 } else {
    1001           0 :                         zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
    1002             :                 }
    1003             : 
    1004           0 :                 if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
    1005           0 :                         efree((char*)EX(function_state).function->common.function_name);
    1006             :                 }
    1007           0 :                 efree(EX(function_state).function);
    1008             : 
    1009           0 :                 if (EG(exception) && fci->retval_ptr_ptr) {
    1010           0 :                         zval_ptr_dtor(fci->retval_ptr_ptr);
    1011           0 :                         *fci->retval_ptr_ptr = NULL;
    1012             :                 }
    1013             :         }
    1014             :         zend_vm_stack_clear_multiple(TSRMLS_C);
    1015             : 
    1016      593692 :         if (EG(This)) {
    1017      362473 :                 zval_ptr_dtor(&EG(This));
    1018             :         }
    1019      593692 :         EG(called_scope) = current_called_scope;
    1020      593692 :         EG(scope) = current_scope;
    1021      593692 :         EG(This) = current_this;
    1022      593692 :         EG(current_execute_data) = EX(prev_execute_data);
    1023             : 
    1024      593692 :         if (EG(exception)) {
    1025         263 :                 zend_throw_exception_internal(NULL TSRMLS_CC);
    1026             :         }
    1027      593689 :         return SUCCESS;
    1028             : }
    1029             : /* }}} */
    1030             : 
    1031      251608 : ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
    1032             : {
    1033             :         zval **args[1];
    1034             :         zval autoload_function;
    1035             :         zval *class_name_ptr;
    1036      251608 :         zval *retval_ptr = NULL;
    1037             :         int retval, lc_length;
    1038             :         char *lc_name;
    1039             :         char *lc_free;
    1040             :         zend_fcall_info fcall_info;
    1041             :         zend_fcall_info_cache fcall_cache;
    1042      251608 :         char dummy = 1;
    1043             :         ulong hash;
    1044             :         ALLOCA_FLAG(use_heap)
    1045             : 
    1046      251608 :         if (key) {
    1047       25161 :                 lc_name = Z_STRVAL(key->constant);
    1048       25161 :                 lc_length = Z_STRLEN(key->constant) + 1;
    1049       25161 :                 hash = key->hash_value;
    1050             :         } else {
    1051      226447 :                 if (name == NULL || !name_length) {
    1052          78 :                         return FAILURE;
    1053             :                 }
    1054             : 
    1055      226369 :                 lc_free = lc_name = do_alloca(name_length + 1, use_heap);
    1056      226369 :                 zend_str_tolower_copy(lc_name, name, name_length);
    1057      226369 :                 lc_length = name_length + 1;
    1058             : 
    1059      226369 :                 if (lc_name[0] == '\\') {
    1060           9 :                         lc_name += 1;
    1061           9 :                         lc_length -= 1;
    1062             :                 }
    1063             : 
    1064      226369 :                 hash = zend_inline_hash_func(lc_name, lc_length);
    1065             :         }
    1066             : 
    1067      251530 :         if (zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce) == SUCCESS) {
    1068      250832 :                 if (!key) {
    1069      225734 :                         free_alloca(lc_free, use_heap);
    1070             :                 }
    1071      250832 :                 return SUCCESS;
    1072             :         }
    1073             : 
    1074             :         /* The compiler is not-reentrant. Make sure we __autoload() only during run-time
    1075             :          * (doesn't impact functionality of __autoload()
    1076             :         */
    1077         698 :         if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
    1078         343 :                 if (!key) {
    1079         339 :                         free_alloca(lc_free, use_heap);
    1080             :                 }
    1081         343 :                 return FAILURE;
    1082             :         }
    1083             : 
    1084             :         /* Verify class name before passing it to __autoload() */
    1085         355 :         if (strspn(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\\") != name_length) {
    1086          26 :                 if (!key) {
    1087          26 :                         free_alloca(lc_free, use_heap);
    1088             :                 }
    1089          26 :                 return FAILURE;
    1090             :         }
    1091             :         
    1092         329 :         if (EG(in_autoload) == NULL) {
    1093         160 :                 ALLOC_HASHTABLE(EG(in_autoload));
    1094         160 :                 zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0);
    1095             :         }
    1096             : 
    1097         329 :         if (zend_hash_quick_add(EG(in_autoload), lc_name, lc_length, hash, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
    1098           4 :                 if (!key) {
    1099           4 :                         free_alloca(lc_free, use_heap);
    1100             :                 }
    1101           4 :                 return FAILURE;
    1102             :         }
    1103             : 
    1104         325 :         ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1, 0);
    1105             : 
    1106         325 :         ALLOC_ZVAL(class_name_ptr);
    1107         325 :         INIT_PZVAL(class_name_ptr);
    1108         325 :         if (name[0] == '\\') {
    1109           1 :                 ZVAL_STRINGL(class_name_ptr, name+1, name_length-1, 1);
    1110             :         } else {
    1111         324 :                 ZVAL_STRINGL(class_name_ptr, name, name_length, 1);
    1112             :         }
    1113             : 
    1114         325 :         args[0] = &class_name_ptr;
    1115             : 
    1116         325 :         fcall_info.size = sizeof(fcall_info);
    1117         325 :         fcall_info.function_table = EG(function_table);
    1118         325 :         fcall_info.function_name = &autoload_function;
    1119         325 :         fcall_info.symbol_table = NULL;
    1120         325 :         fcall_info.retval_ptr_ptr = &retval_ptr;
    1121         325 :         fcall_info.param_count = 1;
    1122         325 :         fcall_info.params = args;
    1123         325 :         fcall_info.object_ptr = NULL;
    1124         325 :         fcall_info.no_separation = 1;
    1125             : 
    1126         325 :         fcall_cache.initialized = EG(autoload_func) ? 1 : 0;
    1127         325 :         fcall_cache.function_handler = EG(autoload_func);
    1128         325 :         fcall_cache.calling_scope = NULL;
    1129         325 :         fcall_cache.called_scope = NULL;
    1130         325 :         fcall_cache.object_ptr = NULL;
    1131             : 
    1132         325 :         zend_exception_save(TSRMLS_C);
    1133         325 :         retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
    1134         320 :         zend_exception_restore(TSRMLS_C);
    1135             : 
    1136         320 :         EG(autoload_func) = fcall_cache.function_handler;
    1137             : 
    1138         320 :         zval_ptr_dtor(&class_name_ptr);
    1139             : 
    1140         320 :         zend_hash_quick_del(EG(in_autoload), lc_name, lc_length, hash);
    1141             : 
    1142         320 :         if (retval_ptr) {
    1143         163 :                 zval_ptr_dtor(&retval_ptr);
    1144             :         }
    1145             : 
    1146         320 :         if (retval == SUCCESS) {
    1147         186 :                 retval = zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce);
    1148             :         }
    1149         320 :         if (!key) {
    1150         264 :                 free_alloca(lc_free, use_heap);
    1151             :         }
    1152         320 :         return retval;
    1153             : }
    1154             : /* }}} */
    1155             : 
    1156      135688 : ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
    1157             : {
    1158      135688 :         return zend_lookup_class_ex(name, name_length, NULL, 1, ce TSRMLS_CC);
    1159             : }
    1160             : /* }}} */
    1161             : 
    1162         142 : ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
    1163             : {
    1164             :         zval pv;
    1165             :         zend_op_array *new_op_array;
    1166         142 :         zend_op_array *original_active_op_array = EG(active_op_array);
    1167             :         zend_uint original_compiler_options;
    1168             :         int retval;
    1169             : 
    1170         142 :         if (retval_ptr) {
    1171          55 :                 Z_STRLEN(pv) = str_len + sizeof("return ;") - 1;
    1172          55 :                 Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
    1173          55 :                 memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
    1174          55 :                 memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len);
    1175          55 :                 Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
    1176          55 :                 Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
    1177             :         } else {
    1178          87 :                 Z_STRLEN(pv) = str_len;
    1179          87 :                 Z_STRVAL(pv) = str;
    1180             :         }
    1181         142 :         Z_TYPE(pv) = IS_STRING;
    1182             : 
    1183             :         /*printf("Evaluating '%s'\n", pv.value.str.val);*/
    1184             : 
    1185         142 :         original_compiler_options = CG(compiler_options);
    1186         142 :         CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
    1187         142 :         new_op_array = zend_compile_string(&pv, string_name TSRMLS_CC);
    1188         142 :         CG(compiler_options) = original_compiler_options;
    1189             : 
    1190         142 :         if (new_op_array) {
    1191         133 :                 zval *local_retval_ptr=NULL;
    1192         133 :                 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
    1193         133 :                 zend_op **original_opline_ptr = EG(opline_ptr);
    1194         133 :                 int orig_interactive = CG(interactive);
    1195             : 
    1196         133 :                 EG(return_value_ptr_ptr) = &local_retval_ptr;
    1197         133 :                 EG(active_op_array) = new_op_array;
    1198         133 :                 EG(no_extensions)=1;
    1199         133 :                 if (!EG(active_symbol_table)) {
    1200           3 :                         zend_rebuild_symbol_table(TSRMLS_C);
    1201             :                 }
    1202         133 :                 CG(interactive) = 0;
    1203             : 
    1204         133 :                 zend_try {
    1205         133 :                         zend_execute(new_op_array TSRMLS_CC);
    1206           1 :                 } zend_catch {
    1207           1 :                         destroy_op_array(new_op_array TSRMLS_CC);
    1208           1 :                         efree(new_op_array);
    1209           1 :                         zend_bailout();
    1210         132 :                 } zend_end_try();
    1211             : 
    1212         132 :                 CG(interactive) = orig_interactive;
    1213         132 :                 if (local_retval_ptr) {
    1214         132 :                         if (retval_ptr) {
    1215         144 :                                 COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
    1216             :                         } else {
    1217          84 :                                 zval_ptr_dtor(&local_retval_ptr);
    1218             :                         }
    1219             :                 } else {
    1220           0 :                         if (retval_ptr) {
    1221           0 :                                 INIT_ZVAL(*retval_ptr);
    1222             :                         }
    1223             :                 }
    1224             : 
    1225         132 :                 EG(no_extensions)=0;
    1226         132 :                 EG(opline_ptr) = original_opline_ptr;
    1227         132 :                 EG(active_op_array) = original_active_op_array;
    1228         132 :                 destroy_op_array(new_op_array TSRMLS_CC);
    1229         132 :                 efree(new_op_array);
    1230         132 :                 EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
    1231         132 :                 retval = SUCCESS;
    1232             :         } else {
    1233           9 :                 retval = FAILURE;
    1234             :         }
    1235         141 :         if (retval_ptr) {
    1236             :                 zval_dtor(&pv);
    1237             :         }
    1238         141 :         return retval;
    1239             : }
    1240             : /* }}} */
    1241             : 
    1242           0 : ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC) /* {{{ */
    1243             : {
    1244           0 :         return zend_eval_stringl(str, strlen(str), retval_ptr, string_name TSRMLS_CC);
    1245             : }
    1246             : /* }}} */
    1247             : 
    1248          23 : ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
    1249             : {
    1250             :         int result;
    1251             : 
    1252          23 :         result = zend_eval_stringl(str, str_len, retval_ptr, string_name TSRMLS_CC);
    1253          22 :         if (handle_exceptions && EG(exception)) {
    1254           0 :                 zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
    1255           0 :                 result = FAILURE;
    1256             :         }
    1257          22 :         return result;
    1258             : }
    1259             : /* }}} */
    1260             : 
    1261          23 : ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC) /* {{{ */
    1262             : {
    1263          23 :         return zend_eval_stringl_ex(str, strlen(str), retval_ptr, string_name, handle_exceptions TSRMLS_CC);
    1264             : }
    1265             : /* }}} */
    1266             : 
    1267           0 : void execute_new_code(TSRMLS_D) /* {{{ */
    1268             : {
    1269             :         zend_op *opline, *end;
    1270             :         zend_op *ret_opline;
    1271             :         int orig_interactive;
    1272             : 
    1273           0 :         if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE)
    1274             :                 || CG(context).backpatch_count>0
    1275           0 :                 || CG(active_op_array)->function_name
    1276           0 :                 || CG(active_op_array)->type!=ZEND_USER_FUNCTION) {
    1277           0 :                 return;
    1278             :         }
    1279             : 
    1280           0 :         ret_opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1281           0 :         ret_opline->opcode = ZEND_RETURN;
    1282           0 :         ret_opline->op1_type = IS_CONST;
    1283           0 :         ret_opline->op1.constant = zend_add_literal(CG(active_op_array), &EG(uninitialized_zval) TSRMLS_CC);
    1284           0 :         SET_UNUSED(ret_opline->op2);
    1285             : 
    1286           0 :         if (!EG(start_op)) {
    1287           0 :                 EG(start_op) = CG(active_op_array)->opcodes;
    1288             :         }
    1289             : 
    1290           0 :         opline=EG(start_op);
    1291           0 :         end=CG(active_op_array)->opcodes+CG(active_op_array)->last;
    1292             : 
    1293           0 :         while (opline<end) {
    1294           0 :                 if (opline->op1_type == IS_CONST) {
    1295           0 :                         opline->op1.zv = &CG(active_op_array)->literals[opline->op1.constant].constant;
    1296             :                 }
    1297           0 :                 if (opline->op2_type == IS_CONST) {
    1298           0 :                         opline->op2.zv = &CG(active_op_array)->literals[opline->op2.constant].constant;
    1299             :                 }
    1300           0 :                 switch (opline->opcode) {
    1301             :                         case ZEND_GOTO:
    1302           0 :                                 if (Z_TYPE_P(opline->op2.zv) != IS_LONG) {
    1303           0 :                                         zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC);
    1304             :                                 }
    1305             :                                 /* break omitted intentionally */
    1306             :                         case ZEND_JMP:
    1307           0 :                                 opline->op1.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.opline_num];
    1308           0 :                                 break;
    1309             :                         case ZEND_JMPZ:
    1310             :                         case ZEND_JMPNZ:
    1311             :                         case ZEND_JMPZ_EX:
    1312             :                         case ZEND_JMPNZ_EX:
    1313             :                         case ZEND_JMP_SET:
    1314             :                         case ZEND_JMP_SET_VAR:
    1315           0 :                                 opline->op2.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.opline_num];
    1316             :                                 break;
    1317             :                 }
    1318           0 :                 ZEND_VM_SET_OPCODE_HANDLER(opline);
    1319           0 :                 opline++;
    1320             :         }
    1321             :         
    1322           0 :         zend_release_labels(1 TSRMLS_CC);
    1323             :         
    1324           0 :         EG(return_value_ptr_ptr) = NULL;
    1325           0 :         EG(active_op_array) = CG(active_op_array);
    1326           0 :         orig_interactive = CG(interactive);
    1327           0 :         CG(interactive) = 0;
    1328           0 :         zend_execute(CG(active_op_array) TSRMLS_CC);
    1329           0 :         CG(interactive) = orig_interactive;
    1330             : 
    1331           0 :         if (EG(exception)) {
    1332           0 :                 zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
    1333             :         }
    1334             : 
    1335           0 :         CG(active_op_array)->last -= 1;      /* get rid of that ZEND_RETURN */
    1336           0 :         EG(start_op) = CG(active_op_array)->opcodes+CG(active_op_array)->last;
    1337             : }
    1338             : /* }}} */
    1339             : 
    1340           3 : ZEND_API void zend_timeout(int dummy) /* {{{ */
    1341             : {
    1342             :         TSRMLS_FETCH();
    1343             : 
    1344           3 :         if (zend_on_timeout) {
    1345             : #ifdef ZEND_SIGNALS
    1346             :                 /* 
    1347             :                    We got here because we got a timeout signal, so we are in a signal handler
    1348             :                    at this point. However, we want to be able to timeout any user-supplied
    1349             :                    shutdown functions, so pretend we are not in a signal handler while we are
    1350             :                    calling these 
    1351             :                 */
    1352             :                 SIGG(running) = 0;
    1353             : #endif
    1354           3 :                 zend_on_timeout(EG(timeout_seconds) TSRMLS_CC);
    1355             :         }
    1356             : 
    1357           3 :         zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s");
    1358           0 : }
    1359             : /* }}} */
    1360             : 
    1361             : #ifdef ZEND_WIN32
    1362             : static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */
    1363             : {
    1364             :         switch (message) {
    1365             :                 case WM_DESTROY:
    1366             :                         PostQuitMessage(0);
    1367             :                         break;
    1368             :                 case WM_REGISTER_ZEND_TIMEOUT:
    1369             :                         /* wParam is the thread id pointer, lParam is the timeout amount in seconds */
    1370             :                         if (lParam == 0) {
    1371             :                                 KillTimer(timeout_window, wParam);
    1372             :                         } else {
    1373             : #ifdef ZTS
    1374             :                                 void ***tsrm_ls;
    1375             : #endif
    1376             :                                 SetTimer(timeout_window, wParam, lParam*1000, NULL);
    1377             : #ifdef ZTS
    1378             :                                 tsrm_ls = ts_resource_ex(0, &wParam);
    1379             :                                 if (!tsrm_ls) {
    1380             :                                         /* shouldn't normally happen */
    1381             :                                         break;
    1382             :                                 }
    1383             : #endif
    1384             :                                 EG(timed_out) = 0;
    1385             :                         }
    1386             :                         break;
    1387             :                 case WM_UNREGISTER_ZEND_TIMEOUT:
    1388             :                         /* wParam is the thread id pointer */
    1389             :                         KillTimer(timeout_window, wParam);
    1390             :                         break;
    1391             :                 case WM_TIMER: {
    1392             : #ifdef ZTS
    1393             :                                 void ***tsrm_ls;
    1394             : 
    1395             :                                 tsrm_ls = ts_resource_ex(0, &wParam);
    1396             :                                 if (!tsrm_ls) {
    1397             :                                         /* Thread died before receiving its timeout? */
    1398             :                                         break;
    1399             :                                 }
    1400             : #endif
    1401             :                                 KillTimer(timeout_window, wParam);
    1402             :                                 EG(timed_out) = 1;
    1403             :                         }
    1404             :                         break;
    1405             :                 default:
    1406             :                         return DefWindowProc(hWnd, message, wParam, lParam);
    1407             :         }
    1408             :         return 0;
    1409             : }
    1410             : /* }}} */
    1411             : 
    1412             : static unsigned __stdcall timeout_thread_proc(void *pArgs) /* {{{ */
    1413             : {
    1414             :         MSG message;
    1415             : 
    1416             :         wc.style=0;
    1417             :         wc.lpfnWndProc = zend_timeout_WndProc;
    1418             :         wc.cbClsExtra=0;
    1419             :         wc.cbWndExtra=0;
    1420             :         wc.hInstance=NULL;
    1421             :         wc.hIcon=NULL;
    1422             :         wc.hCursor=NULL;
    1423             :         wc.hbrBackground=(HBRUSH)(COLOR_BACKGROUND + 5);
    1424             :         wc.lpszMenuName=NULL;
    1425             :         wc.lpszClassName = "Zend Timeout Window";
    1426             :         if (!RegisterClass(&wc)) {
    1427             :                 return -1;
    1428             :         }
    1429             :         timeout_window = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
    1430             :         SetEvent(timeout_thread_event);
    1431             :         while (GetMessage(&message, NULL, 0, 0)) {
    1432             :                 SendMessage(timeout_window, message.message, message.wParam, message.lParam);
    1433             :                 if (message.message == WM_QUIT) {
    1434             :                         break;
    1435             :                 }
    1436             :         }
    1437             :         DestroyWindow(timeout_window);
    1438             :         UnregisterClass(wc.lpszClassName, NULL);
    1439             :         SetEvent(timeout_thread_handle);
    1440             :         return 0;
    1441             : }
    1442             : /* }}} */
    1443             : 
    1444             : void zend_init_timeout_thread(void) /* {{{ */
    1445             : {
    1446             :         timeout_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
    1447             :         timeout_thread_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
    1448             :         _beginthreadex(NULL, 0, timeout_thread_proc, NULL, 0, &timeout_thread_id);
    1449             :         WaitForSingleObject(timeout_thread_event, INFINITE);
    1450             : }
    1451             : /* }}} */
    1452             : 
    1453             : void zend_shutdown_timeout_thread(void) /* {{{ */
    1454             : {
    1455             :         if (!timeout_thread_initialized) {
    1456             :                 return;
    1457             :         }
    1458             :         PostThreadMessage(timeout_thread_id, WM_QUIT, 0, 0);
    1459             : 
    1460             :         /* Wait for thread termination */
    1461             :         WaitForSingleObject(timeout_thread_handle, 5000);
    1462             :         CloseHandle(timeout_thread_handle);
    1463             :         timeout_thread_initialized = 0;
    1464             : }
    1465             : /* }}} */
    1466             : 
    1467             : #endif
    1468             : 
    1469             : /* This one doesn't exists on QNX */
    1470             : #ifndef SIGPROF
    1471             : #define SIGPROF 27
    1472             : #endif
    1473             : 
    1474       20146 : void zend_set_timeout(long seconds, int reset_signals) /* {{{ */
    1475             : {
    1476             :         TSRMLS_FETCH();
    1477             : 
    1478       20146 :         EG(timeout_seconds) = seconds;
    1479             : 
    1480             : #ifdef ZEND_WIN32
    1481             :         if(!seconds) {
    1482             :                 return;
    1483             :         }
    1484             :         if (timeout_thread_initialized == 0 && InterlockedIncrement(&timeout_thread_initialized) == 1) {
    1485             :                 /* We start up this process-wide thread here and not in zend_startup(), because if Zend
    1486             :                  * is initialized inside a DllMain(), you're not supposed to start threads from it.
    1487             :                  */
    1488             :                 zend_init_timeout_thread();
    1489             :         }
    1490             :         PostThreadMessage(timeout_thread_id, WM_REGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) seconds);
    1491             : #else
    1492             : #       ifdef HAVE_SETITIMER
    1493             :         {
    1494             :                 struct itimerval t_r;           /* timeout requested */
    1495             :                 int signo;
    1496             : 
    1497       20146 :                 if(seconds) {
    1498         431 :                         t_r.it_value.tv_sec = seconds;
    1499         431 :                         t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
    1500             : 
    1501             : #       ifdef __CYGWIN__
    1502             :                         setitimer(ITIMER_REAL, &t_r, NULL);
    1503             :                 }
    1504             :                 signo = SIGALRM;
    1505             : #       else
    1506         431 :                         setitimer(ITIMER_PROF, &t_r, NULL);
    1507             :                 }
    1508       20146 :                 signo = SIGPROF;
    1509             : #       endif
    1510             : 
    1511       20146 :                 if (reset_signals) {
    1512             : #       ifdef ZEND_SIGNALS
    1513             :                         zend_signal(signo, zend_timeout TSRMLS_CC);
    1514             : #       else
    1515             :                         sigset_t sigset;
    1516             : 
    1517       20111 :                         signal(signo, zend_timeout);
    1518       20111 :                         sigemptyset(&sigset);
    1519       20111 :                         sigaddset(&sigset, signo);
    1520       20111 :                         sigprocmask(SIG_UNBLOCK, &sigset, NULL);
    1521             : #       endif
    1522             :                 }
    1523             :         }
    1524             : #       endif /* HAVE_SETITIMER */
    1525             : #endif
    1526       20146 : }
    1527             : /* }}} */
    1528             : 
    1529       40327 : void zend_unset_timeout(TSRMLS_D) /* {{{ */
    1530             : {
    1531             : #ifdef ZEND_WIN32
    1532             :         if(timeout_thread_initialized) {
    1533             :                 PostThreadMessage(timeout_thread_id, WM_UNREGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) 0);
    1534             :         }
    1535             : #else
    1536             : #       ifdef HAVE_SETITIMER
    1537       40327 :         if (EG(timeout_seconds)) {
    1538             :                 struct itimerval no_timeout;
    1539             : 
    1540         846 :                 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;
    1541             : 
    1542             : #ifdef __CYGWIN__
    1543             :                 setitimer(ITIMER_REAL, &no_timeout, NULL);
    1544             : #else
    1545         846 :                 setitimer(ITIMER_PROF, &no_timeout, NULL);
    1546             : #endif
    1547             :         }
    1548             : #       endif
    1549             : #endif
    1550       40327 : }
    1551             : /* }}} */
    1552             : 
    1553       92936 : zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC) /* {{{ */
    1554             : {
    1555             :         zend_class_entry **pce;
    1556       92936 :         int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
    1557       92936 :         int silent       = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0;
    1558             : 
    1559       92936 :         fetch_type &= ZEND_FETCH_CLASS_MASK;
    1560             : 
    1561             : check_fetch_type:
    1562       92942 :         switch (fetch_type) {
    1563             :                 case ZEND_FETCH_CLASS_SELF:
    1564        1313 :                         if (!EG(scope)) {
    1565           0 :                                 zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
    1566             :                         }
    1567        1313 :                         return EG(scope);
    1568             :                 case ZEND_FETCH_CLASS_PARENT:
    1569        1226 :                         if (!EG(scope)) {
    1570           0 :                                 zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
    1571             :                         }
    1572        1226 :                         if (!EG(scope)->parent) {
    1573           0 :                                 zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
    1574             :                         }
    1575        1226 :                         return EG(scope)->parent;
    1576             :                 case ZEND_FETCH_CLASS_STATIC:
    1577         104 :                         if (!EG(called_scope)) {
    1578           0 :                                 zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
    1579             :                         }
    1580         104 :                         return EG(called_scope);
    1581             :                 case ZEND_FETCH_CLASS_AUTO: {
    1582       88883 :                                 fetch_type = zend_get_class_fetch_type(class_name, class_name_len);
    1583       88883 :                                 if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {
    1584           6 :                                         goto check_fetch_type;
    1585             :                                 }
    1586             :                         }
    1587             :                         break;
    1588             :         }
    1589             : 
    1590       90293 :         if (zend_lookup_class_ex(class_name, class_name_len, NULL, use_autoload, &pce TSRMLS_CC) == FAILURE) {
    1591          21 :                 if (use_autoload) {
    1592          16 :                         if (!silent && !EG(exception)) {
    1593          13 :                                 if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
    1594           0 :                                         zend_error(E_ERROR, "Interface '%s' not found", class_name);
    1595          13 :                                 } else if (fetch_type == ZEND_FETCH_CLASS_TRAIT) {
    1596           0 :                         zend_error(E_ERROR, "Trait '%s' not found", class_name);
    1597             :                 } else {
    1598          13 :                                         zend_error(E_ERROR, "Class '%s' not found", class_name);
    1599             :                                 }       
    1600             :                         }
    1601             :                 }
    1602           8 :                 return NULL;
    1603             :         }
    1604       90271 :         return *pce;
    1605             : }
    1606             : /* }}} */
    1607             : 
    1608       25170 : zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC) /* {{{ */
    1609             : {
    1610             :         zend_class_entry **pce;
    1611       25170 :         int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
    1612             : 
    1613       25170 :         if (zend_lookup_class_ex(class_name, class_name_len, key, use_autoload, &pce TSRMLS_CC) == FAILURE) {
    1614          27 :                 if (use_autoload) {
    1615          23 :                         if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) {
    1616          15 :                                 if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
    1617           2 :                                         zend_error(E_ERROR, "Interface '%s' not found", class_name);
    1618          13 :                                 } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) {
    1619           2 :                                         zend_error(E_ERROR, "Trait '%s' not found", class_name);
    1620             :                                 } else {
    1621          11 :                                         zend_error(E_ERROR, "Class '%s' not found", class_name);
    1622             :                                 }       
    1623             :                         }
    1624             :                 }
    1625          12 :                 return NULL;
    1626             :         }
    1627       25140 :         return *pce;
    1628             : }
    1629             : /* }}} */
    1630             : 
    1631             : #define MAX_ABSTRACT_INFO_CNT 3
    1632             : #define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
    1633             : #define DISPLAY_ABSTRACT_FN(idx) \
    1634             :         ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
    1635             :         ai.afn[idx] ? "::" : "", \
    1636             :         ai.afn[idx] ? ai.afn[idx]->common.function_name : "", \
    1637             :         ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
    1638             : 
    1639             : typedef struct _zend_abstract_info {
    1640             :         zend_function *afn[MAX_ABSTRACT_INFO_CNT + 1];
    1641             :         int cnt;
    1642             :         int ctor;
    1643             : } zend_abstract_info;
    1644             : 
    1645          43 : static int zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */
    1646             : {
    1647          43 :         if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    1648          14 :                 if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
    1649          14 :                         ai->afn[ai->cnt] = fn;
    1650             :                 }
    1651          14 :                 if (fn->common.fn_flags & ZEND_ACC_CTOR) {
    1652           1 :                         if (!ai->ctor) {
    1653           1 :                                 ai->cnt++;
    1654           1 :                                 ai->ctor = 1;
    1655             :                         } else {
    1656           0 :                                 ai->afn[ai->cnt] = NULL;
    1657             :                         }
    1658             :                 } else {
    1659          13 :                         ai->cnt++;
    1660             :                 }
    1661             :         }
    1662          43 :         return 0;
    1663             : }
    1664             : /* }}} */
    1665             : 
    1666     1303298 : void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    1667             : {
    1668             :         zend_abstract_info ai;
    1669             : 
    1670     1303298 :         if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
    1671          23 :                 memset(&ai, 0, sizeof(ai));
    1672             : 
    1673          23 :                 zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC);
    1674             : 
    1675          23 :                 if (ai.cnt) {
    1676         249 :                         zend_error(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 ")",
    1677             :                                 ce->name, ai.cnt,
    1678          13 :                                 ai.cnt > 1 ? "s" : "",
    1679         103 :                                 DISPLAY_ABSTRACT_FN(0),
    1680          68 :                                 DISPLAY_ABSTRACT_FN(1),
    1681          65 :                                 DISPLAY_ABSTRACT_FN(2)
    1682             :                                 );
    1683             :                 }
    1684             :         }
    1685     1303285 : }
    1686             : /* }}} */
    1687             : 
    1688           1 : ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */
    1689             : {
    1690             :         zend_execute_data *ex;
    1691             :         int i;
    1692             : 
    1693           3 :         for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
    1694           2 :                 if (ex->op_array && ex->symbol_table == symbol_table) {
    1695           1 :                         for (i = 0; i < ex->op_array->last_var; i++) {
    1696           0 :                                 ex->CVs[i] = NULL;
    1697             :                         }
    1698             :                 }
    1699             :         }
    1700           1 : }
    1701             : /* }}} */
    1702             : 
    1703       23158 : ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */
    1704             : {
    1705       23158 :         if (zend_hash_quick_del(ht, name, name_len, hash_value) == SUCCESS) {
    1706       23092 :                 name_len--;
    1707       46196 :                 while (ex && ex->symbol_table == ht) {
    1708             :                         int i;
    1709             : 
    1710          12 :                         if (ex->op_array) {
    1711          26 :                                 for (i = 0; i < ex->op_array->last_var; i++) {
    1712          26 :                                         if (ex->op_array->vars[i].hash_value == hash_value &&
    1713           4 :                                                 ex->op_array->vars[i].name_len == name_len &&
    1714           4 :                                                 !memcmp(ex->op_array->vars[i].name, name, name_len)) {
    1715           4 :                                                 ex->CVs[i] = NULL;
    1716           4 :                                                 break;
    1717             :                                         }
    1718             :                                 }
    1719             :                         }
    1720          12 :                         ex = ex->prev_execute_data;
    1721             :                 }
    1722             :         }
    1723       23157 : }
    1724             : /* }}} */
    1725             : 
    1726         341 : ZEND_API int zend_delete_global_variable_ex(const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */
    1727             : {
    1728             :         zend_execute_data *ex;
    1729             : 
    1730         341 :         if (zend_hash_quick_exists(&EG(symbol_table), name, name_len + 1, hash_value)) {
    1731         345 :                 for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
    1732         172 :                         if (ex->op_array && ex->symbol_table == &EG(symbol_table)) {
    1733             :                                 int i;
    1734         505 :                                 for (i = 0; i < ex->op_array->last_var; i++) {
    1735         379 :                                         if (ex->op_array->vars[i].hash_value == hash_value &&
    1736          12 :                                                 ex->op_array->vars[i].name_len == name_len &&
    1737          12 :                                                 !memcmp(ex->op_array->vars[i].name, name, name_len)
    1738             :                                         ) {
    1739          12 :                                                 ex->CVs[i] = NULL;
    1740          12 :                                                 break;
    1741             :                                         }
    1742             :                                 }
    1743             :                         }
    1744             :                 }
    1745         173 :                 return zend_hash_quick_del(&EG(symbol_table), name, name_len + 1, hash_value);
    1746             :         }
    1747         168 :         return FAILURE;
    1748             : }
    1749             : /* }}} */
    1750             : 
    1751         329 : ZEND_API int zend_delete_global_variable(const char *name, int name_len TSRMLS_DC) /* {{{ */
    1752             : {
    1753         329 :         return zend_delete_global_variable_ex(name, name_len, zend_inline_hash_func(name, name_len + 1) TSRMLS_CC);
    1754             : }
    1755             : /* }}} */
    1756             : 
    1757       34917 : ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
    1758             : {
    1759             :         zend_uint i;
    1760             :         zend_execute_data *ex;
    1761             : 
    1762       34917 :         if (!EG(active_symbol_table)) {
    1763             :                 
    1764             :                 /* Search for last called user function */
    1765       34917 :                 ex = EG(current_execute_data);
    1766       69843 :                 while (ex && !ex->op_array) {
    1767           9 :                         ex = ex->prev_execute_data;
    1768             :                 }
    1769       34917 :                 if (ex && ex->symbol_table) {
    1770           0 :                         EG(active_symbol_table) = ex->symbol_table;
    1771           0 :                         return;
    1772             :                 }
    1773             : 
    1774       34917 :                 if (ex && ex->op_array) {
    1775       34915 :                         if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
    1776             :                                 /*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
    1777       34276 :                                 EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
    1778             :                         } else {
    1779         639 :                                 ALLOC_HASHTABLE(EG(active_symbol_table));
    1780         639 :                                 zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0);
    1781             :                                 /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
    1782             :                         }
    1783       34915 :                         ex->symbol_table = EG(active_symbol_table);
    1784             : 
    1785       34976 :                         if (ex->op_array->this_var != -1 &&
    1786          47 :                             !ex->CVs[ex->op_array->this_var] &&
    1787          14 :                             EG(This)) {
    1788           0 :                                 ex->CVs[ex->op_array->this_var] = (zval**)ex->CVs + ex->op_array->last_var + ex->op_array->this_var;
    1789           0 :                                 *ex->CVs[ex->op_array->this_var] = EG(This);
    1790             :                         }
    1791     1765296 :                         for (i = 0; i < ex->op_array->last_var; i++) {
    1792     1730381 :                                 if (ex->CVs[i]) {
    1793      720523 :                                         zend_hash_quick_update(EG(active_symbol_table),
    1794             :                                                 ex->op_array->vars[i].name,
    1795             :                                                 ex->op_array->vars[i].name_len + 1,
    1796             :                                                 ex->op_array->vars[i].hash_value,
    1797             :                                                 (void**)ex->CVs[i],
    1798             :                                                 sizeof(zval*),
    1799             :                                                 (void**)&ex->CVs[i]);
    1800             :                                 }
    1801             :                         }
    1802             :                 }
    1803             :         }
    1804             : }
    1805             : /* }}} */
    1806             : 
    1807             : /*
    1808             :  * Local variables:
    1809             :  * tab-width: 4
    1810             :  * c-basic-offset: 4
    1811             :  * indent-tabs-mode: t
    1812             :  * End:
    1813             :  */

Generated by: LCOV version 1.10

Generated at Fri, 25 Jul 2014 16:54:15 +0000 (2 days ago)

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