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_builtin_functions.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 895 973 92.0 %
Date: 2014-04-16 Functions: 64 64 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include "zend.h"
      23             : #include "zend_API.h"
      24             : #include "zend_builtin_functions.h"
      25             : #include "zend_constants.h"
      26             : #include "zend_ini.h"
      27             : #include "zend_exceptions.h"
      28             : #include "zend_extensions.h"
      29             : #include "zend_closures.h"
      30             : 
      31             : #undef ZEND_TEST_EXCEPTIONS
      32             : 
      33             : static ZEND_FUNCTION(zend_version);
      34             : static ZEND_FUNCTION(func_num_args);
      35             : static ZEND_FUNCTION(func_get_arg);
      36             : static ZEND_FUNCTION(func_get_args);
      37             : static ZEND_FUNCTION(strlen);
      38             : static ZEND_FUNCTION(strcmp);
      39             : static ZEND_FUNCTION(strncmp);
      40             : static ZEND_FUNCTION(strcasecmp);
      41             : static ZEND_FUNCTION(strncasecmp);
      42             : static ZEND_FUNCTION(each);
      43             : static ZEND_FUNCTION(error_reporting);
      44             : static ZEND_FUNCTION(define);
      45             : static ZEND_FUNCTION(defined);
      46             : static ZEND_FUNCTION(get_class);
      47             : static ZEND_FUNCTION(get_called_class);
      48             : static ZEND_FUNCTION(get_parent_class);
      49             : static ZEND_FUNCTION(method_exists);
      50             : static ZEND_FUNCTION(property_exists);
      51             : static ZEND_FUNCTION(class_exists);
      52             : static ZEND_FUNCTION(interface_exists);
      53             : static ZEND_FUNCTION(trait_exists);
      54             : static ZEND_FUNCTION(function_exists);
      55             : static ZEND_FUNCTION(class_alias);
      56             : #if ZEND_DEBUG
      57             : static ZEND_FUNCTION(leak);
      58             : static ZEND_FUNCTION(leak_variable);
      59             : #ifdef ZEND_TEST_EXCEPTIONS
      60             : static ZEND_FUNCTION(crash);
      61             : #endif
      62             : #endif
      63             : static ZEND_FUNCTION(get_included_files);
      64             : static ZEND_FUNCTION(is_subclass_of);
      65             : static ZEND_FUNCTION(is_a);
      66             : static ZEND_FUNCTION(get_class_vars);
      67             : static ZEND_FUNCTION(get_object_vars);
      68             : static ZEND_FUNCTION(get_class_methods);
      69             : static ZEND_FUNCTION(trigger_error);
      70             : static ZEND_FUNCTION(set_error_handler);
      71             : static ZEND_FUNCTION(restore_error_handler);
      72             : static ZEND_FUNCTION(set_exception_handler);
      73             : static ZEND_FUNCTION(restore_exception_handler);
      74             : static ZEND_FUNCTION(get_declared_classes);
      75             : static ZEND_FUNCTION(get_declared_traits);
      76             : static ZEND_FUNCTION(get_declared_interfaces);
      77             : static ZEND_FUNCTION(get_defined_functions);
      78             : static ZEND_FUNCTION(get_defined_vars);
      79             : static ZEND_FUNCTION(create_function);
      80             : static ZEND_FUNCTION(get_resource_type);
      81             : static ZEND_FUNCTION(get_loaded_extensions);
      82             : static ZEND_FUNCTION(extension_loaded);
      83             : static ZEND_FUNCTION(get_extension_funcs);
      84             : static ZEND_FUNCTION(get_defined_constants);
      85             : static ZEND_FUNCTION(debug_backtrace);
      86             : static ZEND_FUNCTION(debug_print_backtrace);
      87             : #if ZEND_DEBUG
      88             : static ZEND_FUNCTION(zend_test_func);
      89             : #ifdef ZTS
      90             : static ZEND_FUNCTION(zend_thread_id);
      91             : #endif
      92             : #endif
      93             : static ZEND_FUNCTION(gc_collect_cycles);
      94             : static ZEND_FUNCTION(gc_enabled);
      95             : static ZEND_FUNCTION(gc_enable);
      96             : static ZEND_FUNCTION(gc_disable);
      97             : 
      98             : /* {{{ arginfo */
      99             : ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0)
     100             : ZEND_END_ARG_INFO()
     101             : 
     102             : ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
     103             :         ZEND_ARG_INFO(0, arg_num)
     104             : ZEND_END_ARG_INFO()
     105             : 
     106             : ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
     107             :         ZEND_ARG_INFO(0, str)
     108             : ZEND_END_ARG_INFO()
     109             : 
     110             : ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
     111             :         ZEND_ARG_INFO(0, str1)
     112             :         ZEND_ARG_INFO(0, str2)
     113             : ZEND_END_ARG_INFO()
     114             : 
     115             : ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
     116             :         ZEND_ARG_INFO(0, str1)
     117             :         ZEND_ARG_INFO(0, str2)
     118             :         ZEND_ARG_INFO(0, len)
     119             : ZEND_END_ARG_INFO()
     120             : 
     121             : ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
     122             :         ZEND_ARG_INFO(1, arr)
     123             : ZEND_END_ARG_INFO()
     124             : 
     125             : ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 0)
     126             :         ZEND_ARG_INFO(0, new_error_level)
     127             : ZEND_END_ARG_INFO()
     128             : 
     129             : ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 3)
     130             :         ZEND_ARG_INFO(0, constant_name)
     131             :         ZEND_ARG_INFO(0, value)
     132             :         ZEND_ARG_INFO(0, case_insensitive)
     133             : ZEND_END_ARG_INFO()
     134             : 
     135             : ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
     136             :         ZEND_ARG_INFO(0, constant_name)
     137             : ZEND_END_ARG_INFO()
     138             : 
     139             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
     140             :         ZEND_ARG_INFO(0, object)
     141             : ZEND_END_ARG_INFO()
     142             : 
     143             : ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
     144             :         ZEND_ARG_INFO(0, object)
     145             :         ZEND_ARG_INFO(0, class_name)
     146             :         ZEND_ARG_INFO(0, allow_string)
     147             : ZEND_END_ARG_INFO()
     148             : 
     149             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
     150             :         ZEND_ARG_INFO(0, class_name)
     151             : ZEND_END_ARG_INFO()
     152             : 
     153             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
     154             :         ZEND_ARG_INFO(0, obj)
     155             : ZEND_END_ARG_INFO()
     156             : 
     157             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
     158             :         ZEND_ARG_INFO(0, class)
     159             : ZEND_END_ARG_INFO()
     160             : 
     161             : ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
     162             :         ZEND_ARG_INFO(0, object)
     163             :         ZEND_ARG_INFO(0, method)
     164             : ZEND_END_ARG_INFO()
     165             : 
     166             : ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
     167             :         ZEND_ARG_INFO(0, object_or_class)
     168             :         ZEND_ARG_INFO(0, property_name)
     169             : ZEND_END_ARG_INFO()
     170             : 
     171             : ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
     172             :         ZEND_ARG_INFO(0, classname)
     173             :         ZEND_ARG_INFO(0, autoload)
     174             : ZEND_END_ARG_INFO()
     175             : 
     176             : ZEND_BEGIN_ARG_INFO_EX(arginfo_trait_exists, 0, 0, 1)
     177             :         ZEND_ARG_INFO(0, traitname)
     178             :         ZEND_ARG_INFO(0, autoload)
     179             : ZEND_END_ARG_INFO()
     180             : 
     181             : ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
     182             :         ZEND_ARG_INFO(0, function_name)
     183             : ZEND_END_ARG_INFO()
     184             : 
     185             : ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
     186             :         ZEND_ARG_INFO(0, user_class_name)
     187             :         ZEND_ARG_INFO(0, alias_name)
     188             :         ZEND_ARG_INFO(0, autoload)
     189             : ZEND_END_ARG_INFO()
     190             : 
     191             : #if ZEND_DEBUG
     192             : ZEND_BEGIN_ARG_INFO_EX(arginfo_leak_variable, 0, 0, 1)
     193             :         ZEND_ARG_INFO(0, variable)
     194             :         ZEND_ARG_INFO(0, leak_data)
     195             : ZEND_END_ARG_INFO()
     196             : #endif
     197             : 
     198             : ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
     199             :         ZEND_ARG_INFO(0, message)
     200             :         ZEND_ARG_INFO(0, error_type)
     201             : ZEND_END_ARG_INFO()
     202             : 
     203             : ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
     204             :         ZEND_ARG_INFO(0, error_handler)
     205             :         ZEND_ARG_INFO(0, error_types)
     206             : ZEND_END_ARG_INFO()
     207             : 
     208             : ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
     209             :         ZEND_ARG_INFO(0, exception_handler)
     210             : ZEND_END_ARG_INFO()
     211             : 
     212             : ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
     213             :         ZEND_ARG_INFO(0, args)
     214             :         ZEND_ARG_INFO(0, code)
     215             : ZEND_END_ARG_INFO()
     216             : 
     217             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
     218             :         ZEND_ARG_INFO(0, res)
     219             : ZEND_END_ARG_INFO()
     220             : 
     221             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
     222             :         ZEND_ARG_INFO(0, zend_extensions)
     223             : ZEND_END_ARG_INFO()
     224             : 
     225             : ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
     226             :         ZEND_ARG_INFO(0, categorize)
     227             : ZEND_END_ARG_INFO()
     228             : 
     229             : ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
     230             :         ZEND_ARG_INFO(0, options)
     231             :         ZEND_ARG_INFO(0, limit)
     232             : ZEND_END_ARG_INFO()
     233             : 
     234             : ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_print_backtrace, 0, 0, 0)
     235             :         ZEND_ARG_INFO(0, options)
     236             : ZEND_END_ARG_INFO()
     237             : 
     238             : ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
     239             :         ZEND_ARG_INFO(0, extension_name)
     240             : ZEND_END_ARG_INFO()
     241             : /* }}} */
     242             : 
     243             : static const zend_function_entry builtin_functions[] = { /* {{{ */
     244             :         ZEND_FE(zend_version,           arginfo_zend__void)
     245             :         ZEND_FE(func_num_args,          arginfo_zend__void)
     246             :         ZEND_FE(func_get_arg,           arginfo_func_get_arg)
     247             :         ZEND_FE(func_get_args,          arginfo_zend__void)
     248             :         ZEND_FE(strlen,                         arginfo_strlen)
     249             :         ZEND_FE(strcmp,                         arginfo_strcmp)
     250             :         ZEND_FE(strncmp,                        arginfo_strncmp)
     251             :         ZEND_FE(strcasecmp,                     arginfo_strcmp)
     252             :         ZEND_FE(strncasecmp,            arginfo_strncmp)
     253             :         ZEND_FE(each,                           arginfo_each)
     254             :         ZEND_FE(error_reporting,        arginfo_error_reporting)
     255             :         ZEND_FE(define,                         arginfo_define)
     256             :         ZEND_FE(defined,                        arginfo_defined)
     257             :         ZEND_FE(get_class,                      arginfo_get_class)
     258             :         ZEND_FE(get_called_class,       arginfo_zend__void)
     259             :         ZEND_FE(get_parent_class,       arginfo_get_class)
     260             :         ZEND_FE(method_exists,          arginfo_method_exists)
     261             :         ZEND_FE(property_exists,        arginfo_property_exists)
     262             :         ZEND_FE(class_exists,           arginfo_class_exists)
     263             :         ZEND_FE(interface_exists,       arginfo_class_exists)
     264             :         ZEND_FE(trait_exists,           arginfo_trait_exists)
     265             :         ZEND_FE(function_exists,        arginfo_function_exists)
     266             :         ZEND_FE(class_alias,            arginfo_class_alias)
     267             : #if ZEND_DEBUG
     268             :         ZEND_FE(leak,                           NULL)
     269             :         ZEND_FE(leak_variable,          arginfo_leak_variable)
     270             : #ifdef ZEND_TEST_EXCEPTIONS
     271             :         ZEND_FE(crash,                          NULL)
     272             : #endif
     273             : #endif
     274             :         ZEND_FE(get_included_files,     arginfo_zend__void)
     275             :         ZEND_FALIAS(get_required_files, get_included_files,             arginfo_zend__void)
     276             :         ZEND_FE(is_subclass_of,         arginfo_is_subclass_of)
     277             :         ZEND_FE(is_a,                           arginfo_is_subclass_of)
     278             :         ZEND_FE(get_class_vars,         arginfo_get_class_vars)
     279             :         ZEND_FE(get_object_vars,        arginfo_get_object_vars)
     280             :         ZEND_FE(get_class_methods,      arginfo_get_class_methods)
     281             :         ZEND_FE(trigger_error,          arginfo_trigger_error)
     282             :         ZEND_FALIAS(user_error,         trigger_error,          arginfo_trigger_error)
     283             :         ZEND_FE(set_error_handler,                      arginfo_set_error_handler)
     284             :         ZEND_FE(restore_error_handler,          arginfo_zend__void)
     285             :         ZEND_FE(set_exception_handler,          arginfo_set_exception_handler)
     286             :         ZEND_FE(restore_exception_handler,      arginfo_zend__void)
     287             :         ZEND_FE(get_declared_classes,           arginfo_zend__void)
     288             :         ZEND_FE(get_declared_traits,            arginfo_zend__void)
     289             :         ZEND_FE(get_declared_interfaces,        arginfo_zend__void)
     290             :         ZEND_FE(get_defined_functions,          arginfo_zend__void)
     291             :         ZEND_FE(get_defined_vars,                       arginfo_zend__void)
     292             :         ZEND_FE(create_function,                        arginfo_create_function)
     293             :         ZEND_FE(get_resource_type,                      arginfo_get_resource_type)
     294             :         ZEND_FE(get_loaded_extensions,          arginfo_get_loaded_extensions)
     295             :         ZEND_FE(extension_loaded,                       arginfo_extension_loaded)
     296             :         ZEND_FE(get_extension_funcs,            arginfo_extension_loaded)
     297             :         ZEND_FE(get_defined_constants,          arginfo_get_defined_constants)
     298             :         ZEND_FE(debug_backtrace,                        arginfo_debug_backtrace)
     299             :         ZEND_FE(debug_print_backtrace,          arginfo_debug_print_backtrace)
     300             : #if ZEND_DEBUG
     301             :         ZEND_FE(zend_test_func,         NULL)
     302             : #ifdef ZTS
     303             :         ZEND_FE(zend_thread_id,         NULL)
     304             : #endif
     305             : #endif
     306             :         ZEND_FE(gc_collect_cycles,      arginfo_zend__void)
     307             :         ZEND_FE(gc_enabled,             arginfo_zend__void)
     308             :         ZEND_FE(gc_enable,                      arginfo_zend__void)
     309             :         ZEND_FE(gc_disable,             arginfo_zend__void)
     310             :         ZEND_FE_END
     311             : };
     312             : /* }}} */
     313             : 
     314       21159 : ZEND_MINIT_FUNCTION(core) { /* {{{ */
     315             :         zend_class_entry class_entry;
     316             : 
     317       21159 :         INIT_CLASS_ENTRY(class_entry, "stdClass", NULL);
     318       21159 :         zend_standard_class_def = zend_register_internal_class(&class_entry TSRMLS_CC);
     319             : 
     320       21159 :         zend_register_default_classes(TSRMLS_C);
     321             : 
     322       21159 :         return SUCCESS;
     323             : }
     324             : /* }}} */
     325             : 
     326             : zend_module_entry zend_builtin_module = { /* {{{ */
     327             :     STANDARD_MODULE_HEADER,
     328             :         "Core",
     329             :         builtin_functions,
     330             :         ZEND_MINIT(core),
     331             :         NULL,
     332             :         NULL,
     333             :         NULL,
     334             :         NULL,
     335             :         ZEND_VERSION,
     336             :         STANDARD_MODULE_PROPERTIES
     337             : };
     338             : /* }}} */
     339             : 
     340       21159 : int zend_startup_builtin_functions(TSRMLS_D) /* {{{ */
     341             : {
     342       21159 :         zend_builtin_module.module_number = 0;
     343       21159 :         zend_builtin_module.type = MODULE_PERSISTENT;
     344       21159 :         return (EG(current_module) = zend_register_module_ex(&zend_builtin_module TSRMLS_CC)) == NULL ? FAILURE : SUCCESS;
     345             : }
     346             : /* }}} */
     347             : 
     348             : /* {{{ proto string zend_version(void)
     349             :    Get the version of the Zend Engine */
     350         143 : ZEND_FUNCTION(zend_version)
     351             : {
     352         143 :         RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
     353             : }
     354             : /* }}} */
     355             : 
     356             : /* {{{ proto int gc_collect_cycles(void)
     357             :    Forces collection of any existing garbage cycles.
     358             :    Returns number of freed zvals */
     359          45 : ZEND_FUNCTION(gc_collect_cycles)
     360             : {
     361          45 :         RETURN_LONG(gc_collect_cycles(TSRMLS_C));
     362             : }
     363             : /* }}} */
     364             : 
     365             : /* {{{ proto void gc_enabled(void)
     366             :    Returns status of the circular reference collector */
     367           6 : ZEND_FUNCTION(gc_enabled)
     368             : {
     369           6 :         RETURN_BOOL(GC_G(gc_enabled));
     370             : }
     371             : /* }}} */
     372             : 
     373             : /* {{{ proto void gc_enable(void)
     374             :    Activates the circular reference collector */
     375           6 : ZEND_FUNCTION(gc_enable)
     376             : {
     377           6 :         zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     378           6 : }
     379             : /* }}} */
     380             : 
     381             : /* {{{ proto void gc_disable(void)
     382             :    Deactivates the circular reference collector */
     383           3 : ZEND_FUNCTION(gc_disable)
     384             : {
     385           3 :         zend_alter_ini_entry("zend.enable_gc", sizeof("zend.enable_gc"), "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     386           3 : }
     387             : /* }}} */
     388             : 
     389             : /* {{{ proto int func_num_args(void)
     390             :    Get the number of arguments that were passed to the function */
     391          16 : ZEND_FUNCTION(func_num_args)
     392             : {
     393          16 :         zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
     394             : 
     395          16 :         if (ex && ex->function_state.arguments) {
     396          14 :                 RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments));
     397             :         } else {
     398           2 :                 zend_error(E_WARNING, "func_num_args():  Called from the global scope - no function context");
     399           2 :                 RETURN_LONG(-1);
     400             :         }
     401             : }
     402             : /* }}} */
     403             : 
     404             : 
     405             : /* {{{ proto mixed func_get_arg(int arg_num)
     406             :    Get the $arg_num'th argument that was passed to the function */
     407          42 : ZEND_FUNCTION(func_get_arg)
     408             : {
     409             :         void **p;
     410             :         int arg_count;
     411             :         zval *arg;
     412             :         long requested_offset;
     413          42 :         zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
     414             : 
     415          42 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &requested_offset) == FAILURE) {
     416           5 :                 return;
     417             :         }
     418             : 
     419          37 :         if (requested_offset < 0) {
     420           4 :                 zend_error(E_WARNING, "func_get_arg():  The argument number should be >= 0");
     421           4 :                 RETURN_FALSE;
     422             :         }
     423             : 
     424          33 :         if (!ex || !ex->function_state.arguments) {
     425           3 :                 zend_error(E_WARNING, "func_get_arg():  Called from the global scope - no function context");
     426           3 :                 RETURN_FALSE;
     427             :         }
     428             : 
     429          30 :         p = ex->function_state.arguments;
     430          30 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_arg(); */
     431             : 
     432          30 :         if (requested_offset >= arg_count) {
     433          16 :                 zend_error(E_WARNING, "func_get_arg():  Argument %ld not passed to function", requested_offset);
     434          16 :                 RETURN_FALSE;
     435             :         }
     436             : 
     437          14 :         arg = *(p-(arg_count-requested_offset));
     438          56 :         RETURN_ZVAL_FAST(arg);
     439             : }
     440             : /* }}} */
     441             : 
     442             : 
     443             : /* {{{ proto array func_get_args()
     444             :    Get an array of the arguments that were passed to the function */
     445          77 : ZEND_FUNCTION(func_get_args)
     446             : {
     447             :         void **p;
     448             :         int arg_count;
     449             :         int i;
     450          77 :         zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;
     451             : 
     452          77 :         if (!ex || !ex->function_state.arguments) {
     453           2 :                 zend_error(E_WARNING, "func_get_args():  Called from the global scope - no function context");
     454           2 :                 RETURN_FALSE;
     455             :         }
     456             : 
     457          75 :         p = ex->function_state.arguments;
     458          75 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_args(); */
     459             : 
     460          75 :         array_init_size(return_value, arg_count);
     461         156 :         for (i=0; i<arg_count; i++) {
     462             :                 zval *element, *arg;
     463             : 
     464          81 :                 arg = *((zval **) (p-(arg_count-i)));
     465          81 :                 if (!Z_ISREF_P(arg)) {
     466          77 :                         element = arg;
     467          77 :                         Z_ADDREF_P(element);
     468             :                 } else {
     469           4 :                         ALLOC_ZVAL(element);
     470           8 :                         INIT_PZVAL_COPY(element, arg);
     471           4 :                         zval_copy_ctor(element);
     472             :             }
     473          81 :                 zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
     474             :         }
     475             : }
     476             : /* }}} */
     477             : 
     478             : 
     479             : /* {{{ proto int strlen(string str)
     480             :    Get string length */
     481      954092 : ZEND_FUNCTION(strlen)
     482             : {
     483             :         char *s1;
     484             :         int s1_len;
     485             : 
     486      954092 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s1, &s1_len) == FAILURE) {
     487          38 :                 return;
     488             :         }
     489             : 
     490      954054 :         RETVAL_LONG(s1_len);
     491             : }
     492             : /* }}} */
     493             : 
     494             : 
     495             : /* {{{ proto int strcmp(string str1, string str2)
     496             :    Binary safe string comparison */
     497      398997 : ZEND_FUNCTION(strcmp)
     498             : {
     499             :         char *s1, *s2;
     500             :         int s1_len, s2_len;
     501             :         
     502      398997 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
     503           5 :                 return;
     504             :         }
     505             : 
     506      398992 :         RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));
     507             : }
     508             : /* }}} */
     509             : 
     510             : 
     511             : /* {{{ proto int strncmp(string str1, string str2, int len)
     512             :    Binary safe string comparison */
     513       14476 : ZEND_FUNCTION(strncmp)
     514             : {
     515             :         char *s1, *s2;
     516             :         int s1_len, s2_len;
     517             :         long len;
     518             : 
     519       14476 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
     520          20 :                 return;
     521             :         }
     522             : 
     523       14456 :         if (len < 0) {
     524           3 :                 zend_error(E_WARNING, "Length must be greater than or equal to 0");
     525           3 :                 RETURN_FALSE;
     526             :         }
     527             : 
     528       14453 :         RETURN_LONG(zend_binary_strncmp(s1, s1_len, s2, s2_len, len));
     529             : }
     530             : /* }}} */
     531             : 
     532             : 
     533             : /* {{{ proto int strcasecmp(string str1, string str2)
     534             :    Binary safe case-insensitive string comparison */
     535         817 : ZEND_FUNCTION(strcasecmp)
     536             : {
     537             :         char *s1, *s2;
     538             :         int s1_len, s2_len;
     539             :         
     540         817 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
     541           6 :                 return;
     542             :         }
     543             : 
     544         811 :         RETURN_LONG(zend_binary_strcasecmp(s1, s1_len, s2, s2_len));
     545             : }
     546             : /* }}} */
     547             : 
     548             : 
     549             : /* {{{ proto int strncasecmp(string str1, string str2, int len)
     550             :    Binary safe string comparison */
     551       21119 : ZEND_FUNCTION(strncasecmp)
     552             : {
     553             :         char *s1, *s2;
     554             :         int s1_len, s2_len;
     555             :         long len;
     556             : 
     557       21119 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &s1, &s1_len, &s2, &s2_len, &len) == FAILURE) {
     558          32 :                 return;
     559             :         }
     560             : 
     561       21087 :         if (len < 0) {
     562           3 :                 zend_error(E_WARNING, "Length must be greater than or equal to 0");
     563           3 :                 RETURN_FALSE;
     564             :         }
     565             : 
     566       21084 :         RETURN_LONG(zend_binary_strncasecmp(s1, s1_len, s2, s2_len, len));
     567             : }
     568             : /* }}} */
     569             : 
     570             : 
     571             : /* {{{ proto array each(array arr)
     572             :    Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
     573        1452 : ZEND_FUNCTION(each)
     574             : {
     575             :         zval *array, *entry, **entry_ptr, *tmp;
     576             :         char *string_key;
     577             :         uint string_key_len;
     578             :         ulong num_key;
     579             :         zval **inserted_pointer;
     580             :         HashTable *target_hash;
     581             : 
     582        1452 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &array) == FAILURE) {
     583           5 :                 return;
     584             :         }
     585             : 
     586        1447 :         target_hash = HASH_OF(array);
     587        1447 :         if (!target_hash) {
     588          29 :                 zend_error(E_WARNING,"Variable passed to each() is not an array or object");
     589          29 :                 return;
     590             :         }
     591        1418 :         if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
     592          59 :                 RETURN_FALSE;
     593             :         }
     594        1359 :         array_init(return_value);
     595        1359 :         entry = *entry_ptr;
     596             : 
     597             :         /* add value elements */
     598        2718 :         if (Z_ISREF_P(entry)) {
     599           3 :                 ALLOC_ZVAL(tmp);
     600           3 :                 *tmp = *entry;
     601             :                 zval_copy_ctor(tmp);
     602             :                 Z_UNSET_ISREF_P(tmp);
     603             :                 Z_SET_REFCOUNT_P(tmp, 0);
     604           3 :                 entry=tmp;
     605             :         }
     606        1359 :         zend_hash_index_update(return_value->value.ht, 1, &entry, sizeof(zval *), NULL);
     607        1359 :         Z_ADDREF_P(entry);
     608        1359 :         zend_hash_update(return_value->value.ht, "value", sizeof("value"), &entry, sizeof(zval *), NULL);
     609        1359 :         Z_ADDREF_P(entry);
     610             : 
     611             :         /* add the key elements */
     612        1359 :         switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
     613             :                 case HASH_KEY_IS_STRING:
     614          43 :                         add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, !IS_INTERNED(string_key));
     615          43 :                         break;
     616             :                 case HASH_KEY_IS_LONG:
     617        1316 :                         add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
     618             :                         break;
     619             :         }
     620        1359 :         zend_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
     621        1359 :         Z_ADDREF_PP(inserted_pointer);
     622        1359 :         zend_hash_move_forward(target_hash);
     623             : }
     624             : /* }}} */
     625             : 
     626             : 
     627             : /* {{{ proto int error_reporting([int new_error_level])
     628             :    Return the current error_reporting level, and if an argument was passed - change to the new level */
     629        2407 : ZEND_FUNCTION(error_reporting)
     630             : {
     631             :         char *err;
     632             :         int err_len;
     633             :         int old_error_reporting;
     634             : 
     635        2407 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) {
     636           0 :                 return;
     637             :         }
     638             : 
     639        2407 :         old_error_reporting = EG(error_reporting);
     640        2407 :         if(ZEND_NUM_ARGS() != 0) {
     641         379 :                 zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     642             :         }
     643             : 
     644        2407 :         RETVAL_LONG(old_error_reporting);
     645             : }
     646             : /* }}} */
     647             : 
     648             : 
     649             : /* {{{ proto bool define(string constant_name, mixed value, boolean case_insensitive=false)
     650             :    Define a new constant */
     651        3220 : ZEND_FUNCTION(define)
     652             : {
     653             :         char *name;
     654             :         int name_len;
     655             :         zval *val;
     656        3220 :         zval *val_free = NULL;
     657        3220 :         zend_bool non_cs = 0;
     658        3220 :         int case_sensitive = CONST_CS;
     659             :         zend_constant c;
     660             : 
     661        3220 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {
     662           4 :                 return;
     663             :         }
     664             : 
     665        3216 :         if(non_cs) {
     666         127 :                 case_sensitive = 0;
     667             :         }
     668             : 
     669             :         /* class constant, check if there is name and make sure class is valid & exists */
     670        3216 :         if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {
     671           3 :                 zend_error(E_WARNING, "Class constants cannot be defined or redefined");
     672           3 :                 RETURN_FALSE;
     673             :         }
     674             : 
     675             : repeat:
     676        3213 :         switch (Z_TYPE_P(val)) {
     677             :                 case IS_LONG:
     678             :                 case IS_DOUBLE:
     679             :                 case IS_STRING:
     680             :                 case IS_BOOL:
     681             :                 case IS_RESOURCE:
     682             :                 case IS_NULL:
     683        3208 :                         break;
     684             :                 case IS_OBJECT:
     685           4 :                         if (!val_free) {
     686           4 :                                 if (Z_OBJ_HT_P(val)->get) {
     687           0 :                                         val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);
     688           0 :                                         goto repeat;
     689           4 :                                 } else if (Z_OBJ_HT_P(val)->cast_object) {
     690           4 :                                         ALLOC_INIT_ZVAL(val_free);
     691           4 :                                         if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {
     692           1 :                                                 val = val_free;
     693           1 :                                                 break;
     694             :                                         }
     695             :                                 }
     696             :                         }
     697             :                         /* no break */
     698             :                 default:
     699           4 :                         zend_error(E_WARNING,"Constants may only evaluate to scalar values");
     700           4 :                         if (val_free) {
     701           3 :                                 zval_ptr_dtor(&val_free);
     702             :                         }
     703           4 :                         RETURN_FALSE;
     704             :         }
     705             :         
     706        3209 :         c.value = *val;
     707             :         zval_copy_ctor(&c.value);
     708        3209 :         if (val_free) {
     709           1 :                 zval_ptr_dtor(&val_free);
     710             :         }
     711        3209 :         c.flags = case_sensitive; /* non persistent */
     712        3209 :         c.name = str_strndup(name, name_len);
     713        3209 :         if(c.name == NULL) {
     714           0 :                 RETURN_FALSE;
     715             :         }
     716        3209 :         c.name_len = name_len+1;
     717        3209 :         c.module_number = PHP_USER_CONSTANT;
     718        3209 :         if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
     719        3203 :                 RETURN_TRUE;
     720             :         } else {
     721           6 :                 RETURN_FALSE;
     722             :         }
     723             : }
     724             : /* }}} */
     725             : 
     726             : 
     727             : /* {{{ proto bool defined(string constant_name)
     728             :    Check whether a constant exists */
     729         189 : ZEND_FUNCTION(defined)
     730             : {
     731             :         char *name;
     732             :         int name_len;
     733             :         zval c;
     734             : 
     735         189 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
     736           0 :                 return;
     737             :         }
     738             :         
     739         189 :         if (zend_get_constant_ex(name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
     740             :                 zval_dtor(&c);
     741         162 :                 RETURN_TRUE;
     742             :         } else {
     743          27 :                 RETURN_FALSE;
     744             :         }
     745             : }
     746             : /* }}} */
     747             : 
     748             : 
     749             : /* {{{ proto string get_class([object object])
     750             :    Retrieves the class name */
     751         662 : ZEND_FUNCTION(get_class)
     752             : {
     753         662 :         zval *obj = NULL;
     754         662 :         const char *name = "";
     755         662 :         zend_uint name_len = 0;
     756             :         int dup;
     757             : 
     758         662 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &obj) == FAILURE) {
     759          24 :                 RETURN_FALSE;
     760             :         }
     761             : 
     762         638 :         if (!obj) {
     763          12 :                 if (EG(scope)) {
     764           7 :                         RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
     765             :                 } else {
     766           5 :                         zend_error(E_WARNING, "get_class() called without object from outside a class");
     767           5 :                         RETURN_FALSE;
     768             :                 }
     769             :         }
     770             : 
     771         626 :         dup = zend_get_object_classname(obj, &name, &name_len TSRMLS_CC);
     772             : 
     773         626 :         RETURN_STRINGL(name, name_len, dup);
     774             : }
     775             : /* }}} */
     776             : 
     777             : 
     778             : /* {{{ proto string get_called_class()
     779             :    Retrieves the "Late Static Binding" class name */
     780          35 : ZEND_FUNCTION(get_called_class)
     781             : {
     782          35 :         if (zend_parse_parameters_none() == FAILURE) {
     783           0 :                 return;
     784             :         }
     785             : 
     786          35 :         if (EG(called_scope)) {
     787          33 :                 RETURN_STRINGL(EG(called_scope)->name, EG(called_scope)->name_length, 1);
     788           2 :         } else if (!EG(scope))  {
     789           2 :                 zend_error(E_WARNING, "get_called_class() called from outside a class");
     790             :         }
     791           2 :         RETURN_FALSE;
     792             : }
     793             : /* }}} */
     794             : 
     795             : 
     796             : /* {{{ proto string get_parent_class([mixed object])
     797             :    Retrieves the parent class name for object or class or current scope. */
     798          60 : ZEND_FUNCTION(get_parent_class)
     799             : {
     800             :         zval *arg;
     801          60 :         zend_class_entry *ce = NULL;
     802             :         const char *name;
     803             :         zend_uint name_length;
     804             :         
     805          60 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &arg) == FAILURE) {
     806           1 :                 return;
     807             :         }
     808             : 
     809          59 :         if (!ZEND_NUM_ARGS()) {
     810           5 :                 ce = EG(scope);
     811           5 :                 if (ce && ce->parent) {
     812           2 :                         RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
     813             :                 } else {
     814           3 :                         RETURN_FALSE;
     815             :                 }
     816             :         }
     817             : 
     818          54 :         if (Z_TYPE_P(arg) == IS_OBJECT) {
     819          54 :                 if (Z_OBJ_HT_P(arg)->get_class_name
     820          36 :                         && Z_OBJ_HT_P(arg)->get_class_name(arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
     821           3 :                         RETURN_STRINGL(name, name_length, 0);
     822             :                 } else {
     823          15 :                         ce = zend_get_class_entry(arg TSRMLS_CC);
     824             :                 }
     825          36 :         } else if (Z_TYPE_P(arg) == IS_STRING) {
     826             :                 zend_class_entry **pce;
     827             :                 
     828          12 :                 if (zend_lookup_class(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &pce TSRMLS_CC) == SUCCESS) {
     829           5 :                         ce = *pce;
     830             :                 }
     831             :         }
     832             : 
     833          51 :         if (ce && ce->parent) {
     834           2 :                 RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
     835             :         } else {
     836          49 :                 RETURN_FALSE;
     837             :         }
     838             : }
     839             : /* }}} */
     840             : 
     841             : 
     842         359 : static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
     843             : {
     844             :         zval *obj;
     845             :         char *class_name;
     846             :         int class_name_len;
     847             :         zend_class_entry *instance_ce;
     848             :         zend_class_entry **ce;
     849         359 :         zend_bool allow_string = only_subclass;
     850             :         zend_bool retval;
     851             : 
     852         359 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|b", &obj, &class_name, &class_name_len, &allow_string) == FAILURE) {
     853          17 :                 return;
     854             :         }
     855             :         /*
     856             :          * allow_string - is_a default is no, is_subclass_of is yes. 
     857             :          *   if it's allowed, then the autoloader will be called if the class does not exist.
     858             :          *   default behaviour is different, as 'is_a' used to be used to test mixed return values
     859             :          *   and there is no easy way to deprecate this.
     860             :          */
     861             : 
     862         386 :         if (allow_string && Z_TYPE_P(obj) == IS_STRING) {
     863             :                 zend_class_entry **the_ce;
     864          92 :                 if (zend_lookup_class(Z_STRVAL_P(obj), Z_STRLEN_P(obj), &the_ce TSRMLS_CC) == FAILURE) {
     865          48 :                         RETURN_FALSE;
     866             :                 }
     867          44 :                 instance_ce = *the_ce;
     868         350 :         } else if (Z_TYPE_P(obj) == IS_OBJECT && HAS_CLASS_ENTRY(*obj)) {
     869         100 :                 instance_ce = Z_OBJCE_P(obj);
     870             :         } else {
     871         150 :                 RETURN_FALSE;
     872             :         }
     873             : 
     874         144 :         if (zend_lookup_class_ex(class_name, class_name_len, NULL, 0, &ce TSRMLS_CC) == FAILURE) {
     875          63 :                 retval = 0;
     876             :         } else {
     877          96 :                 if (only_subclass && instance_ce == *ce) {
     878          15 :                         retval = 0;
     879             :                 } else {
     880          66 :                         retval = instanceof_function(instance_ce, *ce TSRMLS_CC);
     881             :                 }
     882             :         }
     883             : 
     884         144 :         RETURN_BOOL(retval);
     885             : }
     886             : 
     887             : 
     888             : /* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string=true])
     889             :    Returns true if the object has this class as one of its parents */
     890         199 : ZEND_FUNCTION(is_subclass_of)
     891             : {
     892         199 :         is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     893         199 : }
     894             : /* }}} */
     895             : 
     896             : 
     897             : /* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string=false])
     898             :    Returns true if the first argument is an object and is this class or has this class as one of its parents, */
     899         160 : ZEND_FUNCTION(is_a)
     900             : {
     901         160 :         is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     902         160 : }
     903             : /* }}} */
     904             : 
     905             : 
     906             : /* {{{ add_class_vars */
     907          76 : static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC)
     908             : {
     909             :         HashPosition pos;
     910             :         zend_property_info *prop_info;
     911             :         zval *prop, *prop_copy;
     912             :         char *key;
     913             :         uint key_len;
     914             :         ulong num_index;
     915             : 
     916          76 :         zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos);
     917         556 :         while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS) {
     918         404 :                 zend_hash_get_current_key_ex(&ce->properties_info, &key, &key_len, &num_index, 0, &pos);
     919         404 :                 zend_hash_move_forward_ex(&ce->properties_info, &pos);
     920        1380 :                 if (((prop_info->flags & ZEND_ACC_SHADOW) &&
     921          18 :                      prop_info->ce != EG(scope)) ||
     922         388 :                     ((prop_info->flags & ZEND_ACC_PROTECTED) &&
     923          80 :                      !zend_check_protected(prop_info->ce, EG(scope))) ||
     924         364 :                     ((prop_info->flags & ZEND_ACC_PRIVATE) &&
     925          74 :                       ce != EG(scope) &&
     926          52 :                           prop_info->ce != EG(scope))) {
     927          92 :                         continue;
     928             :                 }
     929         312 :                 prop = NULL;
     930         312 :                 if (prop_info->offset >= 0) {
     931         350 :                         if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
     932          38 :                                 prop = ce->default_static_members_table[prop_info->offset];
     933         274 :                         } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
     934         118 :                                 prop = ce->default_properties_table[prop_info->offset];
     935             :                         }
     936             :                 }
     937         312 :                 if (!prop) {
     938         156 :                         continue;
     939             :                 }
     940             : 
     941             :                 /* copy: enforce read only access */
     942         156 :                 ALLOC_ZVAL(prop_copy);
     943         156 :                 *prop_copy = *prop;
     944         156 :                 zval_copy_ctor(prop_copy);
     945         156 :                 INIT_PZVAL(prop_copy);
     946             : 
     947             :                 /* this is necessary to make it able to work with default array
     948             :                  * properties, returned to user */
     949         156 :                 if (IS_CONSTANT_TYPE(Z_TYPE_P(prop_copy))) {
     950           0 :                         zval_update_constant(&prop_copy, 0 TSRMLS_CC);
     951             :                 }
     952             : 
     953         156 :                 zend_hash_update(Z_ARRVAL_P(return_value), key, key_len, &prop_copy, sizeof(zval*), NULL);
     954             :         }
     955          76 : }
     956             : /* }}} */
     957             : 
     958             : 
     959             : /* {{{ proto array get_class_vars(string class_name)
     960             :    Returns an array of default properties of the class. */
     961          65 : ZEND_FUNCTION(get_class_vars)
     962             : {
     963             :         char *class_name;
     964             :         int class_name_len;
     965             :         zend_class_entry **pce;
     966             : 
     967          65 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
     968           7 :                 return;
     969             :         }
     970             : 
     971          58 :         if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
     972          20 :                 RETURN_FALSE;
     973             :         } else {
     974          38 :                 array_init(return_value);
     975          38 :                 zend_update_class_constants(*pce TSRMLS_CC);
     976          38 :                 add_class_vars(*pce, 0, return_value TSRMLS_CC);
     977          38 :                 add_class_vars(*pce, 1, return_value TSRMLS_CC);
     978             :         }
     979             : }
     980             : /* }}} */
     981             : 
     982             : 
     983             : /* {{{ proto array get_object_vars(object obj)
     984             :    Returns an array of object properties */
     985          73 : ZEND_FUNCTION(get_object_vars)
     986             : {
     987             :         zval *obj;
     988             :         zval **value;
     989             :         HashTable *properties;
     990             :         HashPosition pos;
     991             :         char *key;
     992             :         const char *prop_name, *class_name;
     993             :         uint key_len, prop_len;
     994             :         ulong num_index;
     995             :         zend_object *zobj;
     996             : 
     997          73 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
     998          28 :                 return;
     999             :         }
    1000             : 
    1001          45 :         if (Z_OBJ_HT_P(obj)->get_properties == NULL) {
    1002           0 :                 RETURN_FALSE;
    1003             :         }
    1004             : 
    1005          45 :         properties = Z_OBJ_HT_P(obj)->get_properties(obj TSRMLS_CC);
    1006             : 
    1007          45 :         if (properties == NULL) {
    1008           0 :                 RETURN_FALSE;
    1009             :         }
    1010             : 
    1011          45 :         zobj = zend_objects_get_address(obj TSRMLS_CC);
    1012             : 
    1013          45 :         array_init(return_value);
    1014             : 
    1015          45 :         zend_hash_internal_pointer_reset_ex(properties, &pos);
    1016             : 
    1017         308 :         while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
    1018         218 :                 if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
    1019         215 :                         if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) == SUCCESS) {
    1020         187 :                                 zend_unmangle_property_name_ex(key, key_len - 1, &class_name, &prop_name, (int*) &prop_len);
    1021             :                                 /* Not separating references */
    1022         187 :                                 Z_ADDREF_PP(value);
    1023         224 :                                 if (IS_INTERNED(key) && prop_name != key) {
    1024             :                                         /* we can't use substring of interned string as a new key */
    1025          37 :                                         char *tmp = estrndup(prop_name, prop_len);
    1026          37 :                                         add_assoc_zval_ex(return_value, tmp, prop_len + 1, *value);
    1027          37 :                                         efree(tmp);
    1028             :                                 } else {
    1029         150 :                                         add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value);
    1030             :                                 }
    1031             :                         }
    1032             :                 }
    1033         218 :                 zend_hash_move_forward_ex(properties, &pos);
    1034             :         }
    1035             : }
    1036             : /* }}} */
    1037             : 
    1038          53 : static int same_name(const char *key, const char *name, zend_uint name_len)
    1039             : {
    1040          53 :         char *lcname = zend_str_tolower_dup(name, name_len);
    1041          53 :         int ret = memcmp(lcname, key, name_len) == 0;
    1042          53 :         efree(lcname);
    1043          53 :         return ret;
    1044             : }
    1045             : 
    1046             : /* {{{ proto array get_class_methods(mixed class)
    1047             :    Returns an array of method names for class or class instance. */
    1048          73 : ZEND_FUNCTION(get_class_methods)
    1049             : {
    1050             :         zval *klass;
    1051             :         zval *method_name;
    1052          73 :         zend_class_entry *ce = NULL, **pce;
    1053             :         HashPosition pos;
    1054             :         zend_function *mptr;
    1055             : 
    1056          73 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &klass) == FAILURE) {
    1057           2 :                 return;
    1058             :         }
    1059             : 
    1060          71 :         if (Z_TYPE_P(klass) == IS_OBJECT) {
    1061             :                 /* TBI!! new object handlers */
    1062          10 :                 if (!HAS_CLASS_ENTRY(*klass)) {
    1063           0 :                         RETURN_FALSE;
    1064             :                 }
    1065          10 :                 ce = Z_OBJCE_P(klass);
    1066          61 :         } else if (Z_TYPE_P(klass) == IS_STRING) {
    1067          39 :                 if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == SUCCESS) {
    1068          34 :                         ce = *pce;
    1069             :                 }
    1070             :         }
    1071             : 
    1072          71 :         if (!ce) {
    1073          27 :                 RETURN_NULL();
    1074             :         }
    1075             : 
    1076          44 :         array_init(return_value);
    1077          44 :         zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
    1078             : 
    1079         332 :         while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
    1080         428 :                 if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) 
    1081          63 :                  || (EG(scope) &&
    1082          46 :                      (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
    1083          22 :                        zend_check_protected(mptr->common.scope, EG(scope)))
    1084          29 :                    || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
    1085          24 :                        EG(scope) == mptr->common.scope)))) {
    1086             :                         char *key;
    1087             :                         uint key_len;
    1088             :                         ulong num_index;
    1089         206 :                         uint len = strlen(mptr->common.function_name);
    1090             : 
    1091             :                         /* Do not display old-style inherited constructors */
    1092         206 :                         if (zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING) {
    1093           0 :                                 MAKE_STD_ZVAL(method_name);
    1094           0 :                                 ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
    1095           0 :                                 zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
    1096         229 :                         } else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
    1097          16 :                             mptr->common.scope == ce ||
    1098           7 :                             zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
    1099             : 
    1100         426 :                                 if (mptr->type == ZEND_USER_FUNCTION &&
    1101         112 :                                     *mptr->op_array.refcount > 1 &&
    1102          54 :                                 (len != key_len - 1 ||
    1103          51 :                                  !same_name(key, mptr->common.function_name, len))) {
    1104           3 :                                         MAKE_STD_ZVAL(method_name);
    1105           3 :                                         ZVAL_STRINGL(method_name, zend_find_alias_name(mptr->common.scope, key, key_len - 1), key_len - 1, 1);
    1106           3 :                                         zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
    1107             :                                 } else {
    1108         203 :                                         MAKE_STD_ZVAL(method_name);
    1109         203 :                                         ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
    1110         203 :                                         zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
    1111             :                                 }
    1112             :                         }
    1113             :                 }
    1114         244 :                 zend_hash_move_forward_ex(&ce->function_table, &pos);
    1115             :         }
    1116             : }
    1117             : /* }}} */
    1118             : 
    1119             : 
    1120             : /* {{{ proto bool method_exists(object object, string method)
    1121             :    Checks if the class method exists */
    1122         132 : ZEND_FUNCTION(method_exists)
    1123             : {
    1124             :         zval *klass; 
    1125             :         char *method_name;
    1126             :         int method_len;
    1127             :         char *lcname;
    1128             :         zend_class_entry * ce, **pce;
    1129             : 
    1130         132 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &klass, &method_name, &method_len) == FAILURE) {
    1131           8 :                 return;
    1132             :         }
    1133         124 :         if (Z_TYPE_P(klass) == IS_OBJECT) {
    1134          70 :                 ce = Z_OBJCE_P(klass);
    1135          54 :         } else if (Z_TYPE_P(klass) == IS_STRING) {
    1136          32 :                 if (zend_lookup_class(Z_STRVAL_P(klass), Z_STRLEN_P(klass), &pce TSRMLS_CC) == FAILURE) {
    1137           5 :                         RETURN_FALSE;
    1138             :                 }
    1139          27 :                 ce = *pce;
    1140             :         } else {
    1141          22 :                 RETURN_FALSE;
    1142             :         }
    1143             : 
    1144          97 :         lcname = zend_str_tolower_dup(method_name, method_len);
    1145          97 :         if (zend_hash_exists(&ce->function_table, lcname, method_len+1)) {
    1146          65 :                 efree(lcname);
    1147          65 :                 RETURN_TRUE;
    1148             :         } else {
    1149          32 :                 union _zend_function *func = NULL;
    1150             : 
    1151         122 :                 if (Z_TYPE_P(klass) == IS_OBJECT 
    1152          61 :                 && Z_OBJ_HT_P(klass)->get_method != NULL
    1153          58 :                 && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, method_len, NULL TSRMLS_CC)) != NULL
    1154             :                 ) {
    1155           6 :                         if (func->type == ZEND_INTERNAL_FUNCTION 
    1156           6 :                         && (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0
    1157             :                         ) {
    1158             :                                 /* Returns true to the fake Closure's __invoke */
    1159           3 :                                 RETVAL_BOOL((func->common.scope == zend_ce_closure
    1160             :                                         && (method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
    1161             :                                         && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0) ? 1 : 0);
    1162             :                                         
    1163           3 :                                 efree(lcname);
    1164           3 :                                 efree((char*)((zend_internal_function*)func)->function_name);
    1165           3 :                                 efree(func);
    1166           3 :                                 return;
    1167             :                         }
    1168           0 :                         efree(lcname);
    1169           0 :                         RETURN_TRUE;
    1170             :                 }
    1171             :         }
    1172          29 :         efree(lcname);
    1173          29 :         RETURN_FALSE;
    1174             : }
    1175             : /* }}} */
    1176             : 
    1177             : /* {{{ proto bool property_exists(mixed object_or_class, string property_name)
    1178             :    Checks if the object or class has a property */
    1179         128 : ZEND_FUNCTION(property_exists)
    1180             : {
    1181             :         zval *object;
    1182             :         char *property;
    1183             :         int property_len;
    1184             :         zend_class_entry *ce, **pce;
    1185             :         zend_property_info *property_info;
    1186             :         zval property_z;
    1187             :         ulong h;
    1188             : 
    1189         128 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &object, &property, &property_len) == FAILURE) {
    1190           4 :                 return;
    1191             :         }
    1192             : 
    1193         124 :         if (property_len == 0) {
    1194           7 :                 RETURN_FALSE;
    1195             :         }
    1196             : 
    1197         117 :         if (Z_TYPE_P(object) == IS_STRING) {
    1198          64 :                 if (zend_lookup_class(Z_STRVAL_P(object), Z_STRLEN_P(object), &pce TSRMLS_CC) == FAILURE) {
    1199           2 :                         RETURN_FALSE;
    1200             :                 }
    1201          62 :                 ce = *pce;
    1202          53 :         } else if (Z_TYPE_P(object) == IS_OBJECT) {
    1203          47 :                 ce = Z_OBJCE_P(object);
    1204             :         } else {
    1205           6 :                 zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
    1206           6 :                 RETURN_NULL();
    1207             :         }
    1208             : 
    1209         109 :         h = zend_get_hash_value(property, property_len+1);
    1210         404 :         if (zend_hash_quick_find(&ce->properties_info, property, property_len+1, h, (void **) &property_info) == SUCCESS
    1211         404 :                 && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
    1212          70 :                 RETURN_TRUE;
    1213             :         }
    1214             : 
    1215          39 :         ZVAL_STRINGL(&property_z, property, property_len, 0);
    1216             : 
    1217          85 :         if (Z_TYPE_P(object) ==  IS_OBJECT &&
    1218          23 :                 Z_OBJ_HANDLER_P(object, has_property) && 
    1219          23 :                 Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, 0 TSRMLS_CC)) {
    1220          11 :                 RETURN_TRUE;
    1221             :         }
    1222          28 :         RETURN_FALSE;
    1223             : }
    1224             : /* }}} */
    1225             : 
    1226             : 
    1227             : /* {{{ proto bool class_exists(string classname [, bool autoload])
    1228             :    Checks if the class exists */
    1229         505 : ZEND_FUNCTION(class_exists)
    1230             : {
    1231             :         char *class_name, *lc_name;
    1232             :         zend_class_entry **ce;
    1233             :         int class_name_len;
    1234             :         int found;
    1235         505 :         zend_bool autoload = 1;
    1236             :         ALLOCA_FLAG(use_heap)
    1237             : 
    1238         505 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &class_name, &class_name_len, &autoload) == FAILURE) {
    1239          17 :                 return;
    1240             :         }
    1241             : 
    1242         488 :         if (!autoload) {
    1243             :                 char *name;
    1244             :                 int len;
    1245             : 
    1246          58 :                 lc_name = do_alloca(class_name_len + 1, use_heap);
    1247          58 :                 zend_str_tolower_copy(lc_name, class_name, class_name_len);
    1248             : 
    1249             :                 /* Ignore leading "\" */
    1250          58 :                 name = lc_name;
    1251          58 :                 len = class_name_len;
    1252          58 :                 if (lc_name[0] == '\\') {
    1253           0 :                         name = &lc_name[1];
    1254           0 :                         len--;
    1255             :                 }
    1256             :         
    1257          58 :                 found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
    1258          58 :                 free_alloca(lc_name, use_heap);
    1259          58 :                 RETURN_BOOL(found == SUCCESS && !(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
    1260             :         }
    1261             : 
    1262         430 :         if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1263         356 :                 RETURN_BOOL(((*ce)->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0);
    1264             :         } else {
    1265          74 :                 RETURN_FALSE;
    1266             :         }
    1267             : }
    1268             : /* }}} */
    1269             : 
    1270             : /* {{{ proto bool interface_exists(string classname [, bool autoload])
    1271             :    Checks if the class exists */
    1272         106 : ZEND_FUNCTION(interface_exists)
    1273             : {
    1274             :         char *iface_name, *lc_name;
    1275             :         zend_class_entry **ce;
    1276             :         int iface_name_len;
    1277             :         int found;
    1278         106 :         zend_bool autoload = 1;
    1279             :         ALLOCA_FLAG(use_heap)
    1280             : 
    1281         106 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &iface_name, &iface_name_len, &autoload) == FAILURE) {
    1282          16 :                 return;
    1283             :         }
    1284             : 
    1285          90 :         if (!autoload) {
    1286             :                 char *name;
    1287             :                 int len;
    1288             :                 
    1289          17 :                 lc_name = do_alloca(iface_name_len + 1, use_heap);
    1290          17 :                 zend_str_tolower_copy(lc_name, iface_name, iface_name_len);
    1291             :         
    1292             :                 /* Ignore leading "\" */
    1293          17 :                 name = lc_name;
    1294          17 :                 len = iface_name_len;
    1295          17 :                 if (lc_name[0] == '\\') {
    1296           0 :                         name = &lc_name[1];
    1297           0 :                         len--;
    1298             :                 }
    1299             : 
    1300          17 :                 found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
    1301          17 :                 free_alloca(lc_name, use_heap);
    1302          17 :                 RETURN_BOOL(found == SUCCESS && (*ce)->ce_flags & ZEND_ACC_INTERFACE);
    1303             :         }
    1304             : 
    1305          73 :         if (zend_lookup_class(iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1306          34 :                 RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) > 0);
    1307             :         } else {
    1308          39 :                 RETURN_FALSE;
    1309             :         }
    1310             : }
    1311             : /* }}} */
    1312             : 
    1313             : /* {{{ proto bool trait_exists(string traitname [, bool autoload])
    1314             :  Checks if the trait exists */
    1315          73 : ZEND_FUNCTION(trait_exists)
    1316             : {
    1317             :         char *trait_name, *lc_name;
    1318             :         zend_class_entry **ce;
    1319             :         int trait_name_len;
    1320             :         int found;
    1321          73 :         zend_bool autoload = 1;
    1322             :         ALLOCA_FLAG(use_heap)
    1323             :   
    1324          73 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &trait_name, &trait_name_len, &autoload) == FAILURE) {
    1325          15 :                 return;
    1326             :         }
    1327             :   
    1328          58 :         if (!autoload) {
    1329             :                 char *name;
    1330             :                 int len;
    1331             :                 
    1332          11 :                 lc_name = do_alloca(trait_name_len + 1, use_heap);
    1333          11 :                 zend_str_tolower_copy(lc_name, trait_name, trait_name_len);
    1334             :     
    1335             :                 /* Ignore leading "\" */
    1336          11 :                 name = lc_name;
    1337          11 :                 len = trait_name_len;
    1338          11 :                 if (lc_name[0] == '\\') {
    1339           0 :                         name = &lc_name[1];
    1340           0 :                         len--;
    1341             :                 }
    1342             :     
    1343          11 :                 found = zend_hash_find(EG(class_table), name, len+1, (void **) &ce);
    1344          11 :                 free_alloca(lc_name, use_heap);
    1345          11 :                 RETURN_BOOL(found == SUCCESS && (((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS));
    1346             :         }
    1347             :   
    1348          47 :         if (zend_lookup_class(trait_name, trait_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1349          11 :                 RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
    1350             :         } else {
    1351          36 :                 RETURN_FALSE;
    1352             :         }
    1353             : }
    1354             : /* }}} */
    1355             : 
    1356             : 
    1357             : /* {{{ proto bool function_exists(string function_name) 
    1358             :    Checks if the function exists */
    1359        4904 : ZEND_FUNCTION(function_exists)
    1360             : {
    1361             :         char *name;
    1362             :         int name_len;
    1363             :         zend_function *func;
    1364             :         char *lcname;
    1365             :         zend_bool retval;
    1366             :         
    1367        4904 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
    1368           6 :                 return;
    1369             :         }
    1370             : 
    1371        4898 :         lcname = zend_str_tolower_dup(name, name_len);
    1372             :         
    1373             :         /* Ignore leading "\" */
    1374        4898 :         name = lcname;
    1375        4898 :         if (lcname[0] == '\\') {
    1376           1 :                 name = &lcname[1];
    1377           1 :                 name_len--;
    1378             :         }
    1379             : 
    1380        4898 :         retval = (zend_hash_find(EG(function_table), name, name_len+1, (void **)&func) == SUCCESS);
    1381             :         
    1382        4898 :         efree(lcname);
    1383             : 
    1384             :         /*
    1385             :          * A bit of a hack, but not a bad one: we see if the handler of the function
    1386             :          * is actually one that displays "function is disabled" message.
    1387             :          */
    1388        8105 :         if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
    1389        3207 :                 func->internal_function.handler == zif_display_disabled_function) {
    1390           0 :                 retval = 0;
    1391             :         }
    1392             : 
    1393        4898 :         RETURN_BOOL(retval);
    1394             : }
    1395             : /* }}} */
    1396             : 
    1397             : /* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload])
    1398             :    Creates an alias for user defined class */
    1399          28 : ZEND_FUNCTION(class_alias)
    1400             : {
    1401             :         char *class_name, *alias_name;
    1402             :         zend_class_entry **ce;
    1403             :         int class_name_len, alias_name_len;
    1404             :         int found;
    1405          28 :         zend_bool autoload = 1;
    1406             : 
    1407          28 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &class_name, &class_name_len, &alias_name, &alias_name_len, &autoload) == FAILURE) {
    1408           0 :                 return;
    1409             :         }
    1410             : 
    1411          28 :         found = zend_lookup_class_ex(class_name, class_name_len, NULL, autoload, &ce TSRMLS_CC);
    1412             :         
    1413          28 :         if (found == SUCCESS) {
    1414          27 :                 if ((*ce)->type == ZEND_USER_CLASS) { 
    1415          26 :                         if (zend_register_class_alias_ex(alias_name, alias_name_len, *ce TSRMLS_CC) == SUCCESS) {
    1416          22 :                                 RETURN_TRUE;
    1417             :                         } else {
    1418           4 :                                 zend_error(E_WARNING, "Cannot redeclare class %s", alias_name);
    1419           4 :                                 RETURN_FALSE;
    1420             :                         }
    1421             :                 } else {
    1422           1 :                         zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class");
    1423           1 :                         RETURN_FALSE;
    1424             :                 }
    1425             :         } else {
    1426           1 :                 zend_error(E_WARNING, "Class '%s' not found", class_name);
    1427           1 :                 RETURN_FALSE;
    1428             :         }
    1429             : }
    1430             : /* }}} */
    1431             : 
    1432             : #if ZEND_DEBUG
    1433             : /* {{{ proto void leak(int num_bytes=3)
    1434             :    Cause an intentional memory leak, for testing/debugging purposes */
    1435             : ZEND_FUNCTION(leak)
    1436             : {
    1437             :         long leakbytes=3;
    1438             : 
    1439             :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &leakbytes) == FAILURE) {
    1440             :                 return;
    1441             :         }
    1442             : 
    1443             :         emalloc(leakbytes);
    1444             : }
    1445             : /* }}} */
    1446             : 
    1447             : /* {{{ proto leak_variable(mixed variable [, bool leak_data]) */
    1448             : ZEND_FUNCTION(leak_variable)
    1449             : {
    1450             :         zval *zv;
    1451             :         zend_bool leak_data = 0;
    1452             : 
    1453             :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &zv, &leak_data) == FAILURE) {
    1454             :                 return;
    1455             :         }
    1456             : 
    1457             :         if (!leak_data) {
    1458             :                 zval_add_ref(&zv);
    1459             :         } else if (Z_TYPE_P(zv) == IS_RESOURCE) {
    1460             :                 zend_list_addref(Z_RESVAL_P(zv));
    1461             :         } else if (Z_TYPE_P(zv) == IS_OBJECT) {
    1462             :                 Z_OBJ_HANDLER_P(zv, add_ref)(zv TSRMLS_CC);
    1463             :         } else {
    1464             :                 zend_error(E_WARNING, "Leaking non-zval data is only applicable to resources and objects");
    1465             :         }
    1466             : }
    1467             : /* }}} */
    1468             : 
    1469             : 
    1470             : #ifdef ZEND_TEST_EXCEPTIONS
    1471             : ZEND_FUNCTION(crash)
    1472             : {
    1473             :         char *nowhere=NULL;
    1474             : 
    1475             :         memcpy(nowhere, "something", sizeof("something"));
    1476             : }
    1477             : #endif
    1478             : 
    1479             : #endif /* ZEND_DEBUG */
    1480             : 
    1481             : /* {{{ proto array get_included_files(void)
    1482             :    Returns an array with the file names that were include_once()'d */
    1483          39 : ZEND_FUNCTION(get_included_files)
    1484             : {
    1485             :         char *entry;
    1486             :         uint entry_len;
    1487             : 
    1488          39 :         if (zend_parse_parameters_none() == FAILURE) {
    1489           3 :                 return;
    1490             :         }
    1491             : 
    1492          36 :         array_init(return_value);
    1493          36 :         zend_hash_internal_pointer_reset(&EG(included_files));
    1494         143 :         while (zend_hash_get_current_key_ex(&EG(included_files), &entry, &entry_len, NULL, 0, NULL) == HASH_KEY_IS_STRING) {
    1495          71 :                 add_next_index_stringl(return_value, entry, entry_len-1, !IS_INTERNED(entry));
    1496          71 :                 zend_hash_move_forward(&EG(included_files));
    1497             :         }
    1498             : }
    1499             : /* }}} */
    1500             : 
    1501             : 
    1502             : /* {{{ proto void trigger_error(string message [, int error_type])
    1503             :    Generates a user-level error/warning/notice message */
    1504          22 : ZEND_FUNCTION(trigger_error)
    1505             : {
    1506          22 :         long error_type = E_USER_NOTICE;
    1507             :         char *message;
    1508             :         int message_len;
    1509             : 
    1510          22 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &message, &message_len, &error_type) == FAILURE) {
    1511           2 :                 return;
    1512             :         }
    1513             : 
    1514          20 :         switch (error_type) {
    1515             :                 case E_USER_ERROR:
    1516             :                 case E_USER_WARNING:
    1517             :                 case E_USER_NOTICE:
    1518             :                 case E_USER_DEPRECATED:
    1519          18 :                         break;
    1520             :                 default:
    1521           2 :                         zend_error(E_WARNING, "Invalid error type specified");
    1522           2 :                         RETURN_FALSE;
    1523             :                         break;
    1524             :         }
    1525             : 
    1526          18 :         zend_error((int)error_type, "%s", message);
    1527          17 :         RETURN_TRUE;
    1528             : }
    1529             : /* }}} */
    1530             : 
    1531             : 
    1532             : /* {{{ proto string set_error_handler(string error_handler [, int error_types])
    1533             :    Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error */
    1534         261 : ZEND_FUNCTION(set_error_handler)
    1535             : {
    1536             :         zval *error_handler;
    1537         261 :         char *error_handler_name = NULL;
    1538         261 :         long error_type = E_ALL;
    1539             : 
    1540         261 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) {
    1541           0 :                 return;
    1542             :         }
    1543             : 
    1544         261 :         if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */
    1545         260 :                 if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
    1546           0 :                         zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
    1547           0 :                                            get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
    1548           0 :                         efree(error_handler_name);
    1549           0 :                         return;
    1550             :                 }
    1551         260 :                 efree(error_handler_name);
    1552             :         }
    1553             : 
    1554         261 :         if (EG(user_error_handler)) {
    1555           4 :                 RETVAL_ZVAL(EG(user_error_handler), 1, 0);
    1556             : 
    1557           4 :                 zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
    1558           4 :                 zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
    1559             :         }
    1560             : 
    1561         261 :         if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
    1562           1 :                 EG(user_error_handler) = NULL;
    1563           1 :                 return;
    1564             :         }
    1565             : 
    1566         260 :         ALLOC_ZVAL(EG(user_error_handler));
    1567         780 :         MAKE_COPY_ZVAL(&error_handler, EG(user_error_handler));
    1568         260 :         EG(user_error_handler_error_reporting) = (int)error_type;
    1569             : }
    1570             : /* }}} */
    1571             : 
    1572             : 
    1573             : /* {{{ proto void restore_error_handler(void)
    1574             :    Restores the previously defined error handler function */
    1575           2 : ZEND_FUNCTION(restore_error_handler)
    1576             : {
    1577           2 :         if (EG(user_error_handler)) {
    1578           2 :                 zval *zeh = EG(user_error_handler);
    1579             : 
    1580           2 :                 EG(user_error_handler) = NULL;
    1581           2 :                 zval_ptr_dtor(&zeh);
    1582             :         }
    1583             : 
    1584           2 :         if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
    1585           2 :                 EG(user_error_handler) = NULL;
    1586             :         } else {
    1587           0 :                 EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
    1588           0 :                 zend_stack_del_top(&EG(user_error_handlers_error_reporting));
    1589           0 :                 EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
    1590             :         }
    1591           2 :         RETURN_TRUE;
    1592             : }
    1593             : /* }}} */
    1594             : 
    1595             : 
    1596             : /* {{{ proto string set_exception_handler(callable exception_handler)
    1597             :    Sets a user-defined exception handler function.  Returns the previously defined exception handler, or false on error */
    1598          19 : ZEND_FUNCTION(set_exception_handler)
    1599             : {
    1600             :         zval *exception_handler;
    1601          19 :         char *exception_handler_name = NULL;
    1602             : 
    1603          19 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) {
    1604           2 :                 return;
    1605             :         }
    1606             : 
    1607          17 :         if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
    1608          16 :                 if (!zend_is_callable(exception_handler, 0, &exception_handler_name TSRMLS_CC)) {
    1609           2 :                         zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
    1610           2 :                                            get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown");
    1611           2 :                         efree(exception_handler_name);
    1612           2 :                         return;
    1613             :                 }
    1614          14 :                 efree(exception_handler_name);
    1615             :         }
    1616             : 
    1617          15 :         if (EG(user_exception_handler)) {
    1618           3 :                 RETVAL_ZVAL(EG(user_exception_handler), 1, 0);
    1619             : 
    1620           3 :                 zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler));
    1621             :         }
    1622             : 
    1623          15 :         if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
    1624           1 :                 EG(user_exception_handler) = NULL;
    1625           1 :                 return;
    1626             :         }
    1627             : 
    1628          14 :         ALLOC_ZVAL(EG(user_exception_handler));
    1629          42 :         MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler))
    1630             : }
    1631             : /* }}} */
    1632             : 
    1633             : 
    1634             : /* {{{ proto void restore_exception_handler(void)
    1635             :    Restores the previously defined exception handler function */
    1636           1 : ZEND_FUNCTION(restore_exception_handler)
    1637             : {
    1638           1 :         if (EG(user_exception_handler)) {
    1639           1 :                 zval_ptr_dtor(&EG(user_exception_handler));
    1640             :         }
    1641           1 :         if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) {
    1642           0 :                 EG(user_exception_handler) = NULL;
    1643             :         } else {
    1644           1 :                 EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers));
    1645             :         }
    1646           1 :         RETURN_TRUE;
    1647             : }
    1648             : /* }}} */
    1649             : 
    1650        5104 : static int copy_class_or_interface_name(zend_class_entry **pce TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
    1651             : {
    1652        5104 :         zval *array = va_arg(args, zval *);
    1653        5104 :         zend_uint mask = va_arg(args, zend_uint);
    1654        5104 :         zend_uint comply = va_arg(args, zend_uint);
    1655        5104 :         zend_uint comply_mask = (comply)? mask:0;
    1656        5104 :         zend_class_entry *ce  = *pce;
    1657             : 
    1658       10204 :         if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
    1659        5100 :                 && (comply_mask == (ce->ce_flags & mask))) {
    1660        1799 :                 if (ce->refcount > 1 && 
    1661           2 :                     (ce->name_length != hash_key->nKeyLength - 1 || 
    1662           2 :                      !same_name(hash_key->arKey, ce->name, ce->name_length))) {
    1663           1 :                         add_next_index_stringl(array, hash_key->arKey, hash_key->nKeyLength - 1, 1);
    1664             :                 } else {
    1665        1793 :                         add_next_index_stringl(array, ce->name, ce->name_length, 1);
    1666             :                 }
    1667             :         }
    1668        5104 :         return ZEND_HASH_APPLY_KEEP;
    1669             : }
    1670             : 
    1671             : /* {{{ proto array get_declared_traits()
    1672             :    Returns an array of all declared traits. */
    1673          11 : ZEND_FUNCTION(get_declared_traits)
    1674             : {
    1675          11 :         zend_uint mask = ZEND_ACC_TRAIT;
    1676          11 :         zend_uint comply = 1;
    1677             : 
    1678          11 :         if (zend_parse_parameters_none() == FAILURE) {
    1679           1 :                 return;
    1680             :         }
    1681             : 
    1682          10 :         array_init(return_value);
    1683          10 :         zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1684             : }
    1685             : /* }}} */
    1686             : 
    1687             : 
    1688             : /* {{{ proto array get_declared_classes()
    1689             :    Returns an array of all declared classes. */
    1690          11 : ZEND_FUNCTION(get_declared_classes)
    1691             : {
    1692          11 :         zend_uint mask = ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS);
    1693          11 :         zend_uint comply = 0;
    1694             : 
    1695          11 :         if (zend_parse_parameters_none() == FAILURE) {
    1696           1 :                 return;
    1697             :         }
    1698             : 
    1699          10 :         array_init(return_value);
    1700          10 :         zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1701             : }
    1702             : /* }}} */
    1703             : 
    1704             : /* {{{ proto array get_declared_interfaces()
    1705             :    Returns an array of all declared interfaces. */
    1706          10 : ZEND_FUNCTION(get_declared_interfaces)
    1707             : {
    1708          10 :         zend_uint mask = ZEND_ACC_INTERFACE;
    1709          10 :         zend_uint comply = 1;
    1710             : 
    1711          10 :         if (zend_parse_parameters_none() == FAILURE) {
    1712           2 :                 return;
    1713             :         }
    1714             : 
    1715           8 :         array_init(return_value);
    1716           8 :         zend_hash_apply_with_arguments(EG(class_table) TSRMLS_CC, (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1717             : }
    1718             : /* }}} */
    1719             : 
    1720             : 
    1721        9593 : static int copy_function_name(zend_function *func TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
    1722             : {
    1723        9593 :         zval *internal_ar = va_arg(args, zval *),
    1724        9593 :              *user_ar     = va_arg(args, zval *);
    1725             : 
    1726        9593 :         if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
    1727           0 :                 return 0;
    1728             :         }
    1729             : 
    1730        9593 :         if (func->type == ZEND_INTERNAL_FUNCTION) {
    1731        9584 :                 add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
    1732           9 :         } else if (func->type == ZEND_USER_FUNCTION) {
    1733           9 :                 add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
    1734             :         }
    1735             : 
    1736        9593 :         return 0;
    1737             : }
    1738             : 
    1739             : 
    1740             : /* {{{ proto array get_defined_functions(void)
    1741             :    Returns an array of all defined functions */
    1742           6 : ZEND_FUNCTION(get_defined_functions)
    1743             : {
    1744             :         zval *internal;
    1745             :         zval *user;
    1746             : 
    1747           6 :         if (zend_parse_parameters_none() == FAILURE) {
    1748           2 :                 return;
    1749             :         }
    1750             : 
    1751           4 :         MAKE_STD_ZVAL(internal);
    1752           4 :         MAKE_STD_ZVAL(user);
    1753             : 
    1754           4 :         array_init(internal);
    1755           4 :         array_init(user);
    1756           4 :         array_init(return_value);
    1757             : 
    1758           4 :         zend_hash_apply_with_arguments(EG(function_table) TSRMLS_CC, (apply_func_args_t) copy_function_name, 2, internal, user);
    1759             : 
    1760           4 :         if (zend_hash_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) {
    1761           0 :                 zval_ptr_dtor(&internal);
    1762           0 :                 zval_ptr_dtor(&user);
    1763             :                 zval_dtor(return_value);
    1764           0 :                 zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()");
    1765           0 :                 RETURN_FALSE;
    1766             :         }
    1767             : 
    1768           4 :         if (zend_hash_add(Z_ARRVAL_P(return_value), "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) {
    1769           0 :                 zval_ptr_dtor(&user);
    1770             :                 zval_dtor(return_value);
    1771           0 :                 zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()");
    1772           0 :                 RETURN_FALSE;
    1773             :         }
    1774             : }
    1775             : /* }}} */
    1776             : 
    1777             : 
    1778             : /* {{{ proto array get_defined_vars(void)
    1779             :    Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
    1780          17 : ZEND_FUNCTION(get_defined_vars)
    1781             : {
    1782          17 :         if (!EG(active_symbol_table)) {
    1783           6 :                 zend_rebuild_symbol_table(TSRMLS_C);
    1784             :         }
    1785             : 
    1786          17 :         array_init_size(return_value, zend_hash_num_elements(EG(active_symbol_table)));
    1787             : 
    1788          17 :         zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
    1789             :                                         (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *));
    1790          17 : }
    1791             : /* }}} */
    1792             : 
    1793             : 
    1794             : #define LAMBDA_TEMP_FUNCNAME    "__lambda_func"
    1795             : /* {{{ proto string create_function(string args, string code)
    1796             :    Creates an anonymous function, and returns its name (funny, eh?) */
    1797          59 : ZEND_FUNCTION(create_function)
    1798             : {
    1799             :         char *eval_code, *function_name, *function_args, *function_code;
    1800             :         int eval_code_length, function_name_length, function_args_len, function_code_len;
    1801             :         int retval;
    1802             :         char *eval_name;
    1803             : 
    1804          59 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &function_args, &function_args_len, &function_code, &function_code_len) == FAILURE) {
    1805           0 :                 return;
    1806             :         }
    1807             : 
    1808          59 :         eval_code = (char *) emalloc(sizeof("function " LAMBDA_TEMP_FUNCNAME)
    1809             :                         +function_args_len
    1810             :                         +2      /* for the args parentheses */
    1811             :                         +2      /* for the curly braces */
    1812             :                         +function_code_len);
    1813             : 
    1814          59 :         eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME "(") - 1;
    1815          59 :         memcpy(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(", eval_code_length);
    1816             : 
    1817          59 :         memcpy(eval_code + eval_code_length, function_args, function_args_len);
    1818          59 :         eval_code_length += function_args_len;
    1819             : 
    1820          59 :         eval_code[eval_code_length++] = ')';
    1821          59 :         eval_code[eval_code_length++] = '{';
    1822             : 
    1823          59 :         memcpy(eval_code + eval_code_length, function_code, function_code_len);
    1824          59 :         eval_code_length += function_code_len;
    1825             : 
    1826          59 :         eval_code[eval_code_length++] = '}';
    1827          59 :         eval_code[eval_code_length] = '\0';
    1828             : 
    1829          59 :         eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
    1830          59 :         retval = zend_eval_stringl(eval_code, eval_code_length, NULL, eval_name TSRMLS_CC);
    1831          59 :         efree(eval_code);
    1832          59 :         efree(eval_name);
    1833             : 
    1834          59 :         if (retval==SUCCESS) {
    1835             :                 zend_function new_function, *func;
    1836             : 
    1837          57 :                 if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
    1838           0 :                         zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
    1839           0 :                         RETURN_FALSE;
    1840             :                 }
    1841          57 :                 new_function = *func;
    1842          57 :                 function_add_ref(&new_function);
    1843             : 
    1844          57 :                 function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
    1845          57 :                 function_name[0] = '\0';
    1846             : 
    1847             :                 do {
    1848          57 :                         function_name_length = 1 + snprintf(function_name + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count));
    1849          57 :                 } while (zend_hash_add(EG(function_table), function_name, function_name_length+1, &new_function, sizeof(zend_function), NULL)==FAILURE);
    1850          57 :                 zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
    1851          57 :                 RETURN_STRINGL(function_name, function_name_length, 0);
    1852             :         } else {
    1853           2 :                 zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
    1854           2 :                 RETURN_FALSE;
    1855             :         }
    1856             : }
    1857             : /* }}} */
    1858             : 
    1859             : 
    1860             : #if ZEND_DEBUG
    1861             : ZEND_FUNCTION(zend_test_func)
    1862             : {
    1863             :         zval *arg1, *arg2;
    1864             : 
    1865             :         zend_get_parameters(ht, 2, &arg1, &arg2);
    1866             : }
    1867             : 
    1868             : 
    1869             : #ifdef ZTS
    1870             : ZEND_FUNCTION(zend_thread_id)
    1871             : {
    1872             :         RETURN_LONG((long)tsrm_thread_id());
    1873             : }
    1874             : #endif
    1875             : #endif
    1876             : 
    1877             : /* {{{ proto string get_resource_type(resource res)
    1878             :    Get the resource type name for a given resource */
    1879          77 : ZEND_FUNCTION(get_resource_type)
    1880             : {
    1881             :         const char *resource_type;
    1882             :         zval *z_resource_type;
    1883             : 
    1884          77 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_resource_type) == FAILURE) {
    1885          12 :                 return;
    1886             :         }
    1887             : 
    1888          65 :         resource_type = zend_rsrc_list_get_rsrc_type(Z_LVAL_P(z_resource_type) TSRMLS_CC);
    1889          65 :         if (resource_type) {
    1890          40 :                 RETURN_STRING(resource_type, 1);
    1891             :         } else {
    1892          25 :                 RETURN_STRING("Unknown", 1);
    1893             :         }
    1894             : }
    1895             : /* }}} */
    1896             : 
    1897             : 
    1898         300 : static int add_extension_info(zend_module_entry *module, void *arg TSRMLS_DC)
    1899             : {
    1900         300 :         zval *name_array = (zval *)arg;
    1901         300 :         add_next_index_string(name_array, module->name, 1);
    1902         300 :         return 0;
    1903             : }
    1904             : 
    1905           2 : static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC)
    1906             : {
    1907           2 :         zval *name_array = (zval *)arg;
    1908           2 :         add_next_index_string(name_array, ext->name, 1);
    1909           2 :         return 0;
    1910             : }
    1911             : 
    1912       27878 : static int add_constant_info(zend_constant *constant, void *arg TSRMLS_DC)
    1913             : {
    1914       27878 :         zval *name_array = (zval *)arg;
    1915             :         zval *const_val;
    1916             : 
    1917       27878 :         if (!constant->name) {
    1918             :                 /* skip special constants */
    1919           1 :                 return 0;
    1920             :         }
    1921             : 
    1922       27877 :         MAKE_STD_ZVAL(const_val);
    1923       27877 :         *const_val = constant->value;
    1924             :         zval_copy_ctor(const_val);
    1925       27877 :         INIT_PZVAL(const_val);
    1926       27877 :         add_assoc_zval_ex(name_array, constant->name, constant->name_len, const_val);
    1927       27877 :         return 0;
    1928             : }
    1929             : 
    1930             : 
    1931             : /* {{{ proto array get_loaded_extensions([bool zend_extensions]) U
    1932             :    Return an array containing names of loaded extensions */
    1933           7 : ZEND_FUNCTION(get_loaded_extensions)
    1934             : {
    1935           7 :         zend_bool zendext = 0;
    1936             : 
    1937           7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &zendext) == FAILURE) {
    1938           1 :                 return;
    1939             :         }
    1940             : 
    1941           6 :         array_init(return_value);
    1942             : 
    1943           6 :         if (zendext) {
    1944           2 :                 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) add_zendext_info, return_value TSRMLS_CC);
    1945             :         } else {
    1946           4 :                 zend_hash_apply_with_argument(&module_registry, (apply_func_arg_t) add_extension_info, return_value TSRMLS_CC);
    1947             :         }
    1948             : }
    1949             : /* }}} */
    1950             : 
    1951             : 
    1952             : /* {{{ proto array get_defined_constants([bool categorize])
    1953             :    Return an array containing the names and values of all defined constants */
    1954          39 : ZEND_FUNCTION(get_defined_constants)
    1955             : {
    1956          39 :         zend_bool categorize = 0;
    1957             :         
    1958          39 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &categorize) == FAILURE) {
    1959           2 :                 return;
    1960             :         }
    1961             : 
    1962          37 :         array_init(return_value);
    1963             : 
    1964          37 :         if (categorize) {
    1965             :                 HashPosition pos;
    1966             :                 zend_constant *val;
    1967             :                 int module_number;
    1968             :                 zval **modules;
    1969             :                 char **module_names;
    1970             :                 zend_module_entry *module;
    1971          26 :                 int i = 1;
    1972             : 
    1973          26 :                 modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval *));
    1974          26 :                 module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
    1975             : 
    1976          26 :                 module_names[0] = "internal";
    1977          26 :                 zend_hash_internal_pointer_reset_ex(&module_registry, &pos);
    1978        2002 :                 while (zend_hash_get_current_data_ex(&module_registry, (void *) &module, &pos) != FAILURE) {
    1979        1950 :                         module_names[module->module_number] = (char *)module->name;
    1980        1950 :                         i++;
    1981        1950 :                         zend_hash_move_forward_ex(&module_registry, &pos);
    1982             :                 }
    1983          26 :                 module_names[i] = "user";
    1984             : 
    1985          26 :                 zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos);
    1986       65938 :                 while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &val, &pos) != FAILURE) {
    1987             :                         zval *const_val;
    1988             : 
    1989       65886 :                         if (!val->name) {
    1990             :                                 /* skip special constants */
    1991           1 :                                 goto next_constant;
    1992             :                         }
    1993             : 
    1994       65885 :                         if (val->module_number == PHP_USER_CONSTANT) {
    1995           1 :                                 module_number = i;
    1996       65884 :                         } else if (val->module_number > i || val->module_number < 0) {
    1997             :                                 /* should not happen */
    1998             :                                 goto next_constant;
    1999             :                         } else {
    2000       65884 :                                 module_number = val->module_number;
    2001             :                         }
    2002             : 
    2003       65885 :                         if (!modules[module_number]) {
    2004        1171 :                                 MAKE_STD_ZVAL(modules[module_number]);
    2005        1171 :                                 array_init(modules[module_number]);
    2006        1171 :                                 add_assoc_zval(return_value, module_names[module_number], modules[module_number]);
    2007             :                         }
    2008             : 
    2009       65885 :                         MAKE_STD_ZVAL(const_val);
    2010       65885 :                         *const_val = val->value;
    2011             :                         zval_copy_ctor(const_val);
    2012       65885 :                         INIT_PZVAL(const_val);
    2013             : 
    2014       65885 :                         add_assoc_zval_ex(modules[module_number], val->name, val->name_len, const_val);
    2015             : next_constant:
    2016       65886 :                         zend_hash_move_forward_ex(EG(zend_constants), &pos);
    2017             :                 }
    2018          26 :                 efree(module_names);
    2019          26 :                 efree(modules);
    2020             :         } else {
    2021          11 :                 zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) add_constant_info, return_value TSRMLS_CC);
    2022             :         }
    2023             : }
    2024             : /* }}} */
    2025             : 
    2026             : 
    2027        2882 : static zval *debug_backtrace_get_args(void **curpos TSRMLS_DC)
    2028             : {
    2029        2882 :         void **p = curpos;
    2030             :         zval *arg_array, **arg;
    2031        2882 :         int arg_count = (int)(zend_uintptr_t) *p;
    2032             : 
    2033        2882 :         MAKE_STD_ZVAL(arg_array);
    2034        2882 :         array_init_size(arg_array, arg_count);
    2035        2882 :         p -= arg_count;
    2036             : 
    2037       11093 :         while (--arg_count >= 0) {
    2038        5329 :                 arg = (zval **) p++;
    2039        5329 :                 if (*arg) {
    2040        5329 :                         if (Z_TYPE_PP(arg) != IS_OBJECT) {
    2041       26880 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(arg);
    2042             :                         }
    2043        5329 :                         Z_ADDREF_PP(arg);
    2044        5329 :                         add_next_index_zval(arg_array, *arg);
    2045             :                 } else {
    2046           0 :                         add_next_index_null(arg_array);
    2047             :                 }
    2048             :         }
    2049             : 
    2050        2882 :         return arg_array;
    2051             : }
    2052             : 
    2053          42 : void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
    2054             : {
    2055             :         zval **tmp;
    2056             :         HashPosition iterator;
    2057          42 :         int i = 0;
    2058             : 
    2059          42 :         zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
    2060         135 :         while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
    2061          51 :                 if (i++) {
    2062          29 :                         ZEND_PUTS(", ");
    2063             :                 }
    2064          51 :                 zend_print_flat_zval_r(*tmp TSRMLS_CC);
    2065          51 :                 zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
    2066             :         }
    2067          42 : }
    2068             : 
    2069             : /* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
    2070          28 : ZEND_FUNCTION(debug_print_backtrace)
    2071             : {
    2072             :         zend_execute_data *ptr, *skip;
    2073          28 :         int lineno, frameno = 0;
    2074             :         const char *function_name;
    2075             :         const char *filename;
    2076          28 :         const char *class_name = NULL;
    2077             :         char *call_type;
    2078          28 :         const char *include_filename = NULL;
    2079          28 :         zval *arg_array = NULL;
    2080          28 :         int indent = 0;
    2081          28 :         long options = 0;
    2082          28 :         long limit = 0;
    2083             : 
    2084          28 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &options, &limit) == FAILURE) {
    2085           0 :                 return;
    2086             :         }
    2087             : 
    2088          28 :         ptr = EG(current_execute_data);
    2089             : 
    2090             :         /* skip debug_backtrace() */
    2091          28 :         ptr = ptr->prev_execute_data;
    2092             : 
    2093         115 :         while (ptr && (limit == 0 || frameno < limit)) {
    2094          59 :                 const char *free_class_name = NULL;
    2095             : 
    2096          59 :                 frameno++;
    2097          59 :                 class_name = call_type = NULL;   
    2098          59 :                 arg_array = NULL;
    2099             : 
    2100          59 :                 skip = ptr;
    2101             :                 /* skip internal handler */
    2102          78 :                 if (!skip->op_array &&
    2103           4 :                     skip->prev_execute_data &&
    2104           4 :                     skip->prev_execute_data->opline &&
    2105           4 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
    2106           4 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
    2107           3 :                     skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2108           1 :                         skip = skip->prev_execute_data;
    2109             :                 }
    2110             : 
    2111          59 :                 if (skip->op_array) {
    2112          56 :                         filename = skip->op_array->filename;
    2113          56 :                         lineno = skip->opline->lineno;
    2114             :                 } else {
    2115           3 :                         filename = NULL;
    2116           3 :                         lineno = 0;
    2117             :                 }
    2118             : 
    2119         147 :                 function_name = (ptr->function_state.function->common.scope &&
    2120          29 :                         ptr->function_state.function->common.scope->trait_aliases) ?
    2121          18 :                                 zend_resolve_method_name(
    2122           6 :                                         ptr->object ?
    2123           3 :                                                 Z_OBJCE_P(ptr->object) : 
    2124           3 :                                                 ptr->function_state.function->common.scope,
    2125             :                                         ptr->function_state.function) :
    2126          53 :                                 ptr->function_state.function->common.function_name;
    2127             : 
    2128          59 :                 if (function_name) {
    2129          56 :                         if (ptr->object) {
    2130          15 :                                 if (ptr->function_state.function->common.scope) {
    2131          15 :                                         class_name = ptr->function_state.function->common.scope->name;
    2132             :                                 } else {
    2133             :                                         zend_uint class_name_len;
    2134             :                                         int dup;
    2135             : 
    2136           0 :                                         dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
    2137           0 :                                         if(!dup) {
    2138           0 :                                                 free_class_name = class_name;
    2139             :                                         }
    2140             :                                 }
    2141             : 
    2142          15 :                                 call_type = "->";
    2143          41 :                         } else if (ptr->function_state.function->common.scope) {
    2144          14 :                                 class_name = ptr->function_state.function->common.scope->name;
    2145          14 :                                 call_type = "::";
    2146             :                         } else {
    2147          27 :                                 class_name = NULL;
    2148          27 :                                 call_type = NULL;
    2149             :                         }
    2150          56 :                         if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
    2151          56 :                                 if (ptr->function_state.arguments && (options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
    2152          42 :                                         arg_array = debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC);
    2153             :                                 }
    2154             :                         }
    2155             :                 } else {
    2156             :                         /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
    2157           3 :                         zend_bool build_filename_arg = 1;
    2158             : 
    2159           3 :                         if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2160             :                                 /* can happen when calling eval from a custom sapi */
    2161           0 :                                 function_name = "unknown";
    2162           0 :                                 build_filename_arg = 0;
    2163             :                         } else
    2164           3 :                         switch (ptr->opline->extended_value) {
    2165             :                                 case ZEND_EVAL:
    2166           1 :                                         function_name = "eval";
    2167           1 :                                         build_filename_arg = 0;
    2168           1 :                                         break;
    2169             :                                 case ZEND_INCLUDE:
    2170           2 :                                         function_name = "include";
    2171           2 :                                         break;
    2172             :                                 case ZEND_REQUIRE:
    2173           0 :                                         function_name = "require";
    2174           0 :                                         break;
    2175             :                                 case ZEND_INCLUDE_ONCE:
    2176           0 :                                         function_name = "include_once";
    2177           0 :                                         break;
    2178             :                                 case ZEND_REQUIRE_ONCE:
    2179           0 :                                         function_name = "require_once";
    2180           0 :                                         break;
    2181             :                                 default:
    2182             :                                         /* this can actually happen if you use debug_backtrace() in your error_handler and 
    2183             :                                          * you're in the top-scope */
    2184           0 :                                         function_name = "unknown"; 
    2185           0 :                                         build_filename_arg = 0;
    2186             :                                         break;
    2187             :                         }
    2188             : 
    2189           3 :                         if (build_filename_arg && include_filename) {
    2190           0 :                                 MAKE_STD_ZVAL(arg_array);
    2191           0 :                                 array_init(arg_array);
    2192           0 :                                 add_next_index_string(arg_array, (char*)include_filename, 1);
    2193             :                         }
    2194           3 :                         call_type = NULL;
    2195             :                 }
    2196          59 :                 zend_printf("#%-2d ", indent);
    2197          59 :                 if (class_name) {
    2198          29 :                         ZEND_PUTS(class_name);
    2199          29 :                         ZEND_PUTS(call_type);
    2200             :                 }
    2201          59 :                 zend_printf("%s(", function_name);
    2202          59 :                 if (arg_array) {
    2203          42 :                         debug_print_backtrace_args(arg_array TSRMLS_CC);
    2204          42 :                         zval_ptr_dtor(&arg_array);
    2205             :                 }
    2206          59 :                 if (filename) {
    2207          56 :                         zend_printf(") called at [%s:%d]\n", filename, lineno);
    2208             :                 } else {
    2209           3 :                         zend_execute_data *prev = skip->prev_execute_data;
    2210             : 
    2211           6 :                         while (prev) {
    2212           6 :                                 if (prev->function_state.function &&
    2213           3 :                                         prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
    2214           1 :                                         prev = NULL;
    2215           1 :                                         break;
    2216             :                                 }                                   
    2217           2 :                                 if (prev->op_array) {
    2218           2 :                                         zend_printf(") called at [%s:%d]\n", prev->op_array->filename, prev->opline->lineno);
    2219           2 :                                         break;
    2220             :                                 }
    2221           0 :                                 prev = prev->prev_execute_data;
    2222             :                         }
    2223           3 :                         if (!prev) {
    2224           1 :                                 ZEND_PUTS(")\n");
    2225             :                         }
    2226             :                 }
    2227          59 :                 include_filename = filename;
    2228          59 :                 ptr = skip->prev_execute_data;
    2229          59 :                 ++indent;
    2230          59 :                 if (free_class_name) {
    2231           0 :                         efree((char*)free_class_name);
    2232             :                 }
    2233             :         }
    2234             : }
    2235             : 
    2236             : /* }}} */
    2237             : 
    2238        1714 : ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit TSRMLS_DC)
    2239             : {
    2240             :         zend_execute_data *ptr, *skip;
    2241        1714 :         int lineno, frameno = 0;
    2242             :         const char *function_name;
    2243             :         const char *filename;
    2244             :         const char *class_name;
    2245        1714 :         const char *include_filename = NULL;
    2246             :         zval *stack_frame;
    2247             : 
    2248        1714 :         ptr = EG(current_execute_data);
    2249             : 
    2250             :         /* skip "new Exception()" */
    2251        1714 :         if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
    2252         383 :                 ptr = ptr->prev_execute_data;
    2253             :         }
    2254             : 
    2255             :         /* skip debug_backtrace() */
    2256        1714 :         if (skip_last-- && ptr) {
    2257          45 :                 ptr = ptr->prev_execute_data;
    2258             :         }
    2259             : 
    2260        1714 :         array_init(return_value);
    2261             : 
    2262        6442 :         while (ptr && (limit == 0 || frameno < limit)) {
    2263        3014 :                 frameno++;
    2264        3014 :                 MAKE_STD_ZVAL(stack_frame);
    2265        3014 :                 array_init(stack_frame);
    2266             : 
    2267        3014 :                 skip = ptr;
    2268             :                 /* skip internal handler */
    2269        6229 :                 if (!skip->op_array &&
    2270         946 :                     skip->prev_execute_data &&
    2271         936 :                     skip->prev_execute_data->opline &&
    2272         655 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
    2273         576 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
    2274         102 :                     skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2275         101 :                         skip = skip->prev_execute_data;
    2276             :                 }
    2277             : 
    2278        3014 :                 if (skip->op_array) {
    2279        2169 :                         filename = skip->op_array->filename;
    2280        2169 :                         lineno = skip->opline->lineno;
    2281        2169 :                         add_assoc_string_ex(stack_frame, "file", sizeof("file"), (char*)filename, 1);
    2282        2169 :                         add_assoc_long_ex(stack_frame, "line", sizeof("line"), lineno);
    2283             : 
    2284             :                         /* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
    2285             :                          * and debug_baktrace() might have been called by the error_handler. in this case we don't 
    2286             :                          * want to pop anything of the argument-stack */
    2287             :                 } else {
    2288         845 :                         zend_execute_data *prev = skip->prev_execute_data;
    2289             : 
    2290        1692 :                         while (prev) {
    2291        3328 :                                 if (prev->function_state.function &&
    2292         837 :                                         prev->function_state.function->common.type != ZEND_USER_FUNCTION &&
    2293         827 :                                         !(prev->function_state.function->common.type == ZEND_INTERNAL_FUNCTION &&
    2294         827 :                                                 (prev->function_state.function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER))) {
    2295             :                                         break;
    2296             :                                 }                                   
    2297         274 :                                 if (prev->op_array) {
    2298         272 :                                         add_assoc_string_ex(stack_frame, "file", sizeof("file"), (char*)prev->op_array->filename, 1);
    2299         272 :                                         add_assoc_long_ex(stack_frame, "line", sizeof("line"), prev->opline->lineno);
    2300         272 :                                         break;
    2301             :                                 }
    2302           2 :                                 prev = prev->prev_execute_data;
    2303             :                         }
    2304         845 :                         filename = NULL;
    2305             :                 }
    2306             : 
    2307        8342 :                 function_name = (ptr->function_state.function->common.scope &&
    2308        2314 :                         ptr->function_state.function->common.scope->trait_aliases) ?
    2309           6 :                                 zend_resolve_method_name(
    2310           2 :                                         ptr->object ?
    2311           2 :                                                 Z_OBJCE_P(ptr->object) : 
    2312           0 :                                                 ptr->function_state.function->common.scope,
    2313             :                                         ptr->function_state.function) :
    2314        3012 :                                 ptr->function_state.function->common.function_name;
    2315             : 
    2316        3014 :                 if (function_name) {
    2317        2874 :                         add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1);
    2318             : 
    2319        5005 :                         if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
    2320        2131 :                                 if (ptr->function_state.function->common.scope) {
    2321        2131 :                                         add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)ptr->function_state.function->common.scope->name, 1);
    2322             :                                 } else {
    2323             :                                         zend_uint class_name_len;
    2324             :                                         int dup;
    2325             : 
    2326           0 :                                         dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
    2327           0 :                                         add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)class_name, dup);
    2328             :                                         
    2329             :                                 }
    2330        2131 :                                 if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
    2331          26 :                                         add_assoc_zval_ex(stack_frame, "object", sizeof("object"), ptr->object);
    2332          26 :                                         Z_ADDREF_P(ptr->object);
    2333             :                                 }
    2334             : 
    2335        2131 :                                 add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
    2336         743 :                         } else if (ptr->function_state.function->common.scope) {
    2337         183 :                                 add_assoc_string_ex(stack_frame, "class", sizeof("class"), (char*)ptr->function_state.function->common.scope->name, 1);
    2338         183 :                                 add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
    2339             :                         }
    2340             : 
    2341        7934 :                         if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0 && 
    2342        5060 :                                 ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL)))) {
    2343        2851 :                                 if (ptr->function_state.arguments) {
    2344        2840 :                                         add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(ptr->function_state.arguments TSRMLS_CC));
    2345             :                                 }
    2346             :                         }
    2347             :                 } else {
    2348             :                         /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
    2349         140 :                         zend_bool build_filename_arg = 1;
    2350             : 
    2351         166 :                         if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2352             :                                 /* can happen when calling eval from a custom sapi */
    2353          26 :                                 function_name = "unknown";
    2354          26 :                                 build_filename_arg = 0;
    2355             :                         } else
    2356         114 :                         switch (ptr->opline->extended_value) {
    2357             :                                 case ZEND_EVAL:
    2358          14 :                                         function_name = "eval";
    2359          14 :                                         build_filename_arg = 0;
    2360          14 :                                         break;
    2361             :                                 case ZEND_INCLUDE:
    2362          95 :                                         function_name = "include";
    2363          95 :                                         break;
    2364             :                                 case ZEND_REQUIRE:
    2365           5 :                                         function_name = "require";
    2366           5 :                                         break;
    2367             :                                 case ZEND_INCLUDE_ONCE:
    2368           0 :                                         function_name = "include_once";
    2369           0 :                                         break;
    2370             :                                 case ZEND_REQUIRE_ONCE:
    2371           0 :                                         function_name = "require_once";
    2372           0 :                                         break;
    2373             :                                 default:
    2374             :                                         /* this can actually happen if you use debug_backtrace() in your error_handler and 
    2375             :                                          * you're in the top-scope */
    2376           0 :                                         function_name = "unknown"; 
    2377           0 :                                         build_filename_arg = 0;
    2378             :                                         break;
    2379             :                         }
    2380             : 
    2381         140 :                         if (build_filename_arg && include_filename) {
    2382             :                                 zval *arg_array;
    2383             : 
    2384          98 :                                 MAKE_STD_ZVAL(arg_array);
    2385          98 :                                 array_init(arg_array);
    2386             : 
    2387             :                                 /* include_filename always points to the last filename of the last last called-function.
    2388             :                                    if we have called include in the frame above - this is the file we have included.
    2389             :                                  */
    2390             : 
    2391          98 :                                 add_next_index_string(arg_array, (char*)include_filename, 1);
    2392          98 :                                 add_assoc_zval_ex(stack_frame, "args", sizeof("args"), arg_array);
    2393             :                         }
    2394             : 
    2395         140 :                         add_assoc_string_ex(stack_frame, "function", sizeof("function"), (char*)function_name, 1);
    2396             :                 }
    2397             : 
    2398        3014 :                 add_next_index_zval(return_value, stack_frame);
    2399             : 
    2400        3014 :                 include_filename = filename; 
    2401             : 
    2402        3014 :                 ptr = skip->prev_execute_data;
    2403             :         }
    2404        1714 : }
    2405             : /* }}} */
    2406             : 
    2407             : 
    2408             : /* {{{ proto array debug_backtrace([int options[, int limit]])
    2409             :    Return backtrace as array */
    2410          43 : ZEND_FUNCTION(debug_backtrace)
    2411             : {
    2412          43 :         long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
    2413          43 :         long limit = 0;
    2414             :         
    2415          43 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &options, &limit) == FAILURE) {
    2416           0 :                 return;
    2417             :         }
    2418             : 
    2419          43 :         zend_fetch_debug_backtrace(return_value, 1, options, limit TSRMLS_CC);
    2420             : }
    2421             : /* }}} */
    2422             : 
    2423             : /* {{{ proto bool extension_loaded(string extension_name)
    2424             :    Returns true if the named extension is loaded */
    2425       19275 : ZEND_FUNCTION(extension_loaded)
    2426             : {
    2427             :         char *extension_name;
    2428             :         int extension_name_len;
    2429             :         char *lcname;
    2430             : 
    2431       19275 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
    2432           0 :                 return;
    2433             :         }
    2434             : 
    2435       19275 :         lcname = zend_str_tolower_dup(extension_name, extension_name_len);
    2436       19275 :         if (zend_hash_exists(&module_registry, lcname, extension_name_len+1)) {
    2437       19272 :                 RETVAL_TRUE;
    2438             :         } else {
    2439           3 :                 RETVAL_FALSE;
    2440             :         }
    2441       19275 :         efree(lcname);
    2442             : }
    2443             : /* }}} */
    2444             : 
    2445             : 
    2446             : /* {{{ proto array get_extension_funcs(string extension_name)
    2447             :    Returns an array with the names of functions belonging to the named extension */
    2448          34 : ZEND_FUNCTION(get_extension_funcs)
    2449             : {
    2450             :         char *extension_name, *lcname;
    2451             :         int extension_name_len, array;
    2452             :         zend_module_entry *module;
    2453             :         HashPosition iterator;
    2454             :         zend_function *zif;
    2455          34 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) {
    2456           7 :                 return;
    2457             :         }
    2458          27 :         if (strncasecmp(extension_name, "zend", sizeof("zend"))) {
    2459          25 :                 lcname = zend_str_tolower_dup(extension_name, extension_name_len);
    2460             :         } else {
    2461           2 :                 lcname = estrdup("core");
    2462             :         }
    2463          54 :         if (zend_hash_find(&module_registry, lcname,
    2464          27 :                 extension_name_len+1, (void**)&module) == FAILURE) {
    2465          20 :                 efree(lcname);
    2466          20 :                 RETURN_FALSE;
    2467             :         }
    2468             : 
    2469           7 :         zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator);
    2470           7 :         if (module->functions) {
    2471             :                 /* avoid BC break, if functions list is empty, will return an empty array */
    2472           7 :                 array_init(return_value);
    2473           7 :                 array = 1;
    2474             :         } else {
    2475           0 :                 array = 0;
    2476             :         }
    2477       16791 :         while (zend_hash_get_current_data_ex(CG(function_table), (void **) &zif, &iterator) == SUCCESS) {
    2478       50326 :                 if (zif->common.type==ZEND_INTERNAL_FUNCTION
    2479       33549 :                         && zif->internal_function.module == module) {
    2480        2387 :                         if (!array) {
    2481           0 :                                 array_init(return_value);
    2482           0 :                                 array = 1;
    2483             :                         }
    2484        2387 :                         add_next_index_string(return_value, zif->common.function_name, 1);
    2485             :                 }
    2486       16777 :                 zend_hash_move_forward_ex(CG(function_table), &iterator);
    2487             :         }
    2488             : 
    2489           7 :         efree(lcname);
    2490             : 
    2491           7 :         if (!array) {
    2492           0 :                 RETURN_FALSE;
    2493             :         }
    2494             : }
    2495             : /* }}} */
    2496             : 
    2497             : /*
    2498             :  * Local variables:
    2499             :  * tab-width: 4
    2500             :  * c-basic-offset: 4
    2501             :  * indent-tabs-mode: t
    2502             :  * End:
    2503             :  */

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:43 +0000 (4 days ago)

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