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: 646 784 82.4 %
Date: 2014-04-18 Functions: 35 42 83.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:23 +0000 (5 days ago)

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