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: 994 1094 90.9 %
Date: 2015-09-02 Functions: 67 68 98.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 02 Sep 2015 17:19:05 +0000 (2 days ago)

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