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

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