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: 591 704 83.9 %
Date: 2015-03-20 Functions: 39 44 88.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 20 Mar 2015 23:40:23 +0000 (7 days ago)

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