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: 601 707 85.0 %
Date: 2014-09-27 Functions: 41 45 91.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 27 Sep 2014 16:43:05 +0000 (3 days ago)

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