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