root/Zend/zend_builtin_functions.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_MINIT_FUNCTION
  2. zend_startup_builtin_functions
  3. ZEND_FUNCTION
  4. ZEND_FUNCTION
  5. ZEND_FUNCTION
  6. ZEND_FUNCTION
  7. ZEND_FUNCTION
  8. ZEND_FUNCTION
  9. ZEND_FUNCTION
  10. ZEND_FUNCTION
  11. ZEND_FUNCTION
  12. ZEND_FUNCTION
  13. ZEND_FUNCTION
  14. ZEND_FUNCTION
  15. ZEND_FUNCTION
  16. ZEND_FUNCTION
  17. ZEND_FUNCTION
  18. ZEND_FUNCTION
  19. validate_constant_array
  20. copy_constant_array
  21. ZEND_FUNCTION
  22. ZEND_FUNCTION
  23. ZEND_FUNCTION
  24. ZEND_FUNCTION
  25. ZEND_FUNCTION
  26. is_a_impl
  27. ZEND_FUNCTION
  28. ZEND_FUNCTION
  29. add_class_vars
  30. ZEND_FUNCTION
  31. ZEND_FUNCTION
  32. same_name
  33. ZEND_FUNCTION
  34. ZEND_FUNCTION
  35. ZEND_FUNCTION
  36. ZEND_FUNCTION
  37. ZEND_FUNCTION
  38. ZEND_FUNCTION
  39. ZEND_FUNCTION
  40. ZEND_FUNCTION
  41. ZEND_FUNCTION
  42. ZEND_FUNCTION
  43. ZEND_FUNCTION
  44. ZEND_FUNCTION
  45. ZEND_FUNCTION
  46. ZEND_FUNCTION
  47. ZEND_FUNCTION
  48. ZEND_FUNCTION
  49. ZEND_FUNCTION
  50. copy_class_or_interface_name
  51. ZEND_FUNCTION
  52. ZEND_FUNCTION
  53. ZEND_FUNCTION
  54. copy_function_name
  55. ZEND_FUNCTION
  56. ZEND_FUNCTION
  57. ZEND_FUNCTION
  58. ZEND_FUNCTION
  59. ZEND_FUNCTION
  60. ZEND_FUNCTION
  61. ZEND_FUNCTION
  62. ZEND_FUNCTION
  63. add_extension_info
  64. add_zendext_info
  65. add_constant_info
  66. ZEND_FUNCTION
  67. ZEND_FUNCTION
  68. debug_backtrace_get_args
  69. debug_print_backtrace_args
  70. ZEND_FUNCTION
  71. zend_fetch_debug_backtrace
  72. ZEND_FUNCTION
  73. ZEND_FUNCTION
  74. ZEND_FUNCTION

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

/* [<][>][^][v][top][bottom][index][help] */