summaryrefslogtreecommitdiff
path: root/Zend/zend_builtin_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_builtin_functions.c')
-rw-r--r--Zend/zend_builtin_functions.c1105
1 files changed, 287 insertions, 818 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 33dfea0ea7..5ec365c920 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -27,281 +27,8 @@
#include "zend_extensions.h"
#include "zend_closures.h"
#include "zend_generators.h"
+#include "zend_builtin_functions_arginfo.h"
-static ZEND_FUNCTION(zend_version);
-static ZEND_FUNCTION(func_num_args);
-static ZEND_FUNCTION(func_get_arg);
-static ZEND_FUNCTION(func_get_args);
-static ZEND_FUNCTION(strlen);
-static ZEND_FUNCTION(strcmp);
-static ZEND_FUNCTION(strncmp);
-static ZEND_FUNCTION(strcasecmp);
-static ZEND_FUNCTION(strncasecmp);
-static ZEND_FUNCTION(each);
-static ZEND_FUNCTION(error_reporting);
-static ZEND_FUNCTION(define);
-static ZEND_FUNCTION(defined);
-static ZEND_FUNCTION(get_class);
-static ZEND_FUNCTION(get_called_class);
-static ZEND_FUNCTION(get_parent_class);
-static ZEND_FUNCTION(method_exists);
-static ZEND_FUNCTION(property_exists);
-static ZEND_FUNCTION(class_exists);
-static ZEND_FUNCTION(interface_exists);
-static ZEND_FUNCTION(trait_exists);
-static ZEND_FUNCTION(function_exists);
-static ZEND_FUNCTION(class_alias);
-static ZEND_FUNCTION(get_included_files);
-static ZEND_FUNCTION(is_subclass_of);
-static ZEND_FUNCTION(is_a);
-static ZEND_FUNCTION(get_class_vars);
-static ZEND_FUNCTION(get_object_vars);
-static ZEND_FUNCTION(get_mangled_object_vars);
-static ZEND_FUNCTION(get_class_methods);
-static ZEND_FUNCTION(trigger_error);
-static ZEND_FUNCTION(set_error_handler);
-static ZEND_FUNCTION(restore_error_handler);
-static ZEND_FUNCTION(set_exception_handler);
-static ZEND_FUNCTION(restore_exception_handler);
-static ZEND_FUNCTION(get_declared_classes);
-static ZEND_FUNCTION(get_declared_traits);
-static ZEND_FUNCTION(get_declared_interfaces);
-static ZEND_FUNCTION(get_defined_functions);
-static ZEND_FUNCTION(get_defined_vars);
-static ZEND_FUNCTION(create_function);
-static ZEND_FUNCTION(get_resource_type);
-static ZEND_FUNCTION(get_resources);
-static ZEND_FUNCTION(get_loaded_extensions);
-static ZEND_FUNCTION(extension_loaded);
-static ZEND_FUNCTION(get_extension_funcs);
-static ZEND_FUNCTION(get_defined_constants);
-static ZEND_FUNCTION(debug_backtrace);
-static ZEND_FUNCTION(debug_print_backtrace);
-#if ZEND_DEBUG && defined(ZTS)
-static ZEND_FUNCTION(zend_thread_id);
-#endif
-static ZEND_FUNCTION(gc_mem_caches);
-static ZEND_FUNCTION(gc_collect_cycles);
-static ZEND_FUNCTION(gc_enabled);
-static ZEND_FUNCTION(gc_enable);
-static ZEND_FUNCTION(gc_disable);
-static ZEND_FUNCTION(gc_status);
-
-/* {{{ arginfo */
-ZEND_BEGIN_ARG_INFO(arginfo_zend__void, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_func_get_arg, 0, 0, 1)
- ZEND_ARG_INFO(0, arg_num)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_strlen, 0, 0, 1)
- ZEND_ARG_INFO(0, str)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_strcmp, 0, 0, 2)
- ZEND_ARG_INFO(0, str1)
- ZEND_ARG_INFO(0, str2)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_strncmp, 0, 0, 3)
- ZEND_ARG_INFO(0, str1)
- ZEND_ARG_INFO(0, str2)
- ZEND_ARG_INFO(0, len)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_each, 0, 0, 1)
- ZEND_ARG_INFO(1, arr)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_error_reporting, 0, 0, 0)
- ZEND_ARG_INFO(0, new_error_level)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_define, 0, 0, 2)
- ZEND_ARG_INFO(0, constant_name)
- ZEND_ARG_INFO(0, value)
- ZEND_ARG_INFO(0, case_insensitive)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_defined, 0, 0, 1)
- ZEND_ARG_INFO(0, constant_name)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class, 0, 0, 0)
- ZEND_ARG_INFO(0, object)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_is_subclass_of, 0, 0, 2)
- ZEND_ARG_INFO(0, object)
- ZEND_ARG_INFO(0, class_name)
- ZEND_ARG_INFO(0, allow_string)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_vars, 0, 0, 1)
- ZEND_ARG_INFO(0, class_name)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
- ZEND_ARG_INFO(0, obj)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_mangled_object_vars, 0, 0, 1)
- ZEND_ARG_INFO(0, obj)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
- ZEND_ARG_INFO(0, class)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_method_exists, 0, 0, 2)
- ZEND_ARG_INFO(0, object)
- ZEND_ARG_INFO(0, method)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_property_exists, 0, 0, 2)
- ZEND_ARG_INFO(0, object_or_class)
- ZEND_ARG_INFO(0, property_name)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_exists, 0, 0, 1)
- ZEND_ARG_INFO(0, classname)
- ZEND_ARG_INFO(0, autoload)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_trait_exists, 0, 0, 1)
- ZEND_ARG_INFO(0, traitname)
- ZEND_ARG_INFO(0, autoload)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_function_exists, 0, 0, 1)
- ZEND_ARG_INFO(0, function_name)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_alias, 0, 0, 2)
- ZEND_ARG_INFO(0, user_class_name)
- ZEND_ARG_INFO(0, alias_name)
- ZEND_ARG_INFO(0, autoload)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_trigger_error, 0, 0, 1)
- ZEND_ARG_INFO(0, message)
- ZEND_ARG_INFO(0, error_type)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_set_error_handler, 0, 0, 1)
- ZEND_ARG_INFO(0, error_handler)
- ZEND_ARG_INFO(0, error_types)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_set_exception_handler, 0, 0, 1)
- ZEND_ARG_INFO(0, exception_handler)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_functions, 0, 0, 0)
- ZEND_ARG_INFO(0, exclude_disabled)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_create_function, 0, 0, 2)
- ZEND_ARG_INFO(0, args)
- ZEND_ARG_INFO(0, code)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resource_type, 0, 0, 1)
- ZEND_ARG_INFO(0, res)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_resources, 0, 0, 0)
- ZEND_ARG_INFO(0, type)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_loaded_extensions, 0, 0, 0)
- ZEND_ARG_INFO(0, zend_extensions)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_get_defined_constants, 0, 0, 0)
- ZEND_ARG_INFO(0, categorize)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_backtrace, 0, 0, 0)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, limit)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_debug_print_backtrace, 0, 0, 0)
- ZEND_ARG_INFO(0, options)
- ZEND_ARG_INFO(0, limit)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_extension_loaded, 0, 0, 1)
- ZEND_ARG_INFO(0, extension_name)
-ZEND_END_ARG_INFO()
-
-/* }}} */
-
-static const zend_function_entry builtin_functions[] = { /* {{{ */
- ZEND_FE(zend_version, arginfo_zend__void)
- ZEND_FE(func_num_args, arginfo_zend__void)
- ZEND_FE(func_get_arg, arginfo_func_get_arg)
- ZEND_FE(func_get_args, arginfo_zend__void)
- ZEND_FE(strlen, arginfo_strlen)
- ZEND_FE(strcmp, arginfo_strcmp)
- ZEND_FE(strncmp, arginfo_strncmp)
- ZEND_FE(strcasecmp, arginfo_strcmp)
- ZEND_FE(strncasecmp, arginfo_strncmp)
- ZEND_FE(each, arginfo_each)
- ZEND_FE(error_reporting, arginfo_error_reporting)
- ZEND_FE(define, arginfo_define)
- ZEND_FE(defined, arginfo_defined)
- ZEND_FE(get_class, arginfo_get_class)
- ZEND_FE(get_called_class, arginfo_zend__void)
- ZEND_FE(get_parent_class, arginfo_get_class)
- ZEND_FE(method_exists, arginfo_method_exists)
- ZEND_FE(property_exists, arginfo_property_exists)
- ZEND_FE(class_exists, arginfo_class_exists)
- ZEND_FE(interface_exists, arginfo_class_exists)
- ZEND_FE(trait_exists, arginfo_trait_exists)
- ZEND_FE(function_exists, arginfo_function_exists)
- ZEND_FE(class_alias, arginfo_class_alias)
- ZEND_FE(get_included_files, arginfo_zend__void)
- ZEND_FALIAS(get_required_files, get_included_files, arginfo_zend__void)
- ZEND_FE(is_subclass_of, arginfo_is_subclass_of)
- ZEND_FE(is_a, arginfo_is_subclass_of)
- ZEND_FE(get_class_vars, arginfo_get_class_vars)
- ZEND_FE(get_object_vars, arginfo_get_object_vars)
- ZEND_FE(get_mangled_object_vars, arginfo_get_mangled_object_vars)
- ZEND_FE(get_class_methods, arginfo_get_class_methods)
- ZEND_FE(trigger_error, arginfo_trigger_error)
- ZEND_FALIAS(user_error, trigger_error, arginfo_trigger_error)
- ZEND_FE(set_error_handler, arginfo_set_error_handler)
- ZEND_FE(restore_error_handler, arginfo_zend__void)
- ZEND_FE(set_exception_handler, arginfo_set_exception_handler)
- ZEND_FE(restore_exception_handler, arginfo_zend__void)
- ZEND_FE(get_declared_classes, arginfo_zend__void)
- ZEND_FE(get_declared_traits, arginfo_zend__void)
- ZEND_FE(get_declared_interfaces, arginfo_zend__void)
- ZEND_FE(get_defined_functions, arginfo_get_defined_functions)
- ZEND_FE(get_defined_vars, arginfo_zend__void)
- ZEND_DEP_FE(create_function, arginfo_create_function)
- ZEND_FE(get_resource_type, arginfo_get_resource_type)
- ZEND_FE(get_resources, arginfo_get_resources)
- ZEND_FE(get_loaded_extensions, arginfo_get_loaded_extensions)
- ZEND_FE(extension_loaded, arginfo_extension_loaded)
- ZEND_FE(get_extension_funcs, arginfo_extension_loaded)
- ZEND_FE(get_defined_constants, arginfo_get_defined_constants)
- ZEND_FE(debug_backtrace, arginfo_debug_backtrace)
- ZEND_FE(debug_print_backtrace, arginfo_debug_print_backtrace)
-#if ZEND_DEBUG && defined(ZTS)
- ZEND_FE(zend_thread_id, NULL)
-#endif
- ZEND_FE(gc_mem_caches, arginfo_zend__void)
- ZEND_FE(gc_collect_cycles, arginfo_zend__void)
- ZEND_FE(gc_enabled, arginfo_zend__void)
- ZEND_FE(gc_enable, arginfo_zend__void)
- ZEND_FE(gc_disable, arginfo_zend__void)
- ZEND_FE(gc_status, arginfo_zend__void)
- ZEND_FE_END
-};
/* }}} */
ZEND_MINIT_FUNCTION(core) { /* {{{ */
@@ -319,7 +46,7 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */
zend_module_entry zend_builtin_module = { /* {{{ */
STANDARD_MODULE_HEADER,
"Core",
- builtin_functions,
+ ext_functions,
ZEND_MINIT(core),
NULL,
NULL,
@@ -330,7 +57,7 @@ zend_module_entry zend_builtin_module = { /* {{{ */
};
/* }}} */
-int zend_startup_builtin_functions(void) /* {{{ */
+zend_result zend_startup_builtin_functions(void) /* {{{ */
{
zend_builtin_module.module_number = 0;
zend_builtin_module.type = MODULE_PERSISTENT;
@@ -338,65 +65,50 @@ int zend_startup_builtin_functions(void) /* {{{ */
}
/* }}} */
-/* {{{ proto string zend_version(void)
- Get the version of the Zend Engine */
+/* {{{ Get the version of the Zend Engine */
ZEND_FUNCTION(zend_version)
{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1);
}
/* }}} */
-/* {{{ proto int gc_mem_caches(void)
- Reclaims memory used by MM caches.
+/* {{{ Reclaims memory used by MM caches.
Returns number of freed bytes */
ZEND_FUNCTION(gc_mem_caches)
{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
RETURN_LONG(zend_mm_gc(zend_mm_get_heap()));
}
/* }}} */
-/* {{{ proto int gc_collect_cycles(void)
- Forces collection of any existing garbage cycles.
+/* {{{ Forces collection of any existing garbage cycles.
Returns number of freed zvals */
ZEND_FUNCTION(gc_collect_cycles)
{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
RETURN_LONG(gc_collect_cycles());
}
/* }}} */
-/* {{{ proto void gc_enabled(void)
- Returns status of the circular reference collector */
+/* {{{ Returns status of the circular reference collector */
ZEND_FUNCTION(gc_enabled)
{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
RETURN_BOOL(gc_enabled());
}
/* }}} */
-/* {{{ proto void gc_enable(void)
- Activates the circular reference collector */
+/* {{{ Activates the circular reference collector */
ZEND_FUNCTION(gc_enable)
{
zend_string *key;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
key = zend_string_init("zend.enable_gc", sizeof("zend.enable_gc")-1, 0);
zend_alter_ini_entry_chars(key, "1", sizeof("1")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
@@ -404,15 +116,12 @@ ZEND_FUNCTION(gc_enable)
}
/* }}} */
-/* {{{ proto void gc_disable(void)
- Deactivates the circular reference collector */
+/* {{{ Deactivates the circular reference collector */
ZEND_FUNCTION(gc_disable)
{
zend_string *key;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
key = zend_string_init("zend.enable_gc", sizeof("zend.enable_gc")-1, 0);
zend_alter_ini_entry_chars(key, "0", sizeof("0")-1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
@@ -420,15 +129,12 @@ ZEND_FUNCTION(gc_disable)
}
/* }}} */
-/* {{{ proto array gc_status(void)
- Returns current GC statistics */
+/* {{{ Returns current GC statistics */
ZEND_FUNCTION(gc_status)
{
zend_gc_status status;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
zend_gc_get_status(&status);
@@ -441,19 +147,16 @@ ZEND_FUNCTION(gc_status)
}
/* }}} */
-/* {{{ proto int func_num_args(void)
- Get the number of arguments that were passed to the function */
+/* {{{ Get the number of arguments that were passed to the function */
ZEND_FUNCTION(func_num_args)
{
zend_execute_data *ex = EX(prev_execute_data);
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
if (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE) {
- zend_error(E_WARNING, "func_num_args(): Called from the global scope - no function context");
- RETURN_LONG(-1);
+ zend_throw_error(NULL, "func_num_args() must be called from a function context");
+ RETURN_THROWS();
}
if (zend_forbid_dynamic_call("func_num_args()") == FAILURE) {
@@ -464,8 +167,7 @@ ZEND_FUNCTION(func_num_args)
}
/* }}} */
-/* {{{ proto mixed func_get_arg(int arg_num)
- Get the $arg_num'th argument that was passed to the function */
+/* {{{ Get the $arg_num'th argument that was passed to the function */
ZEND_FUNCTION(func_get_arg)
{
uint32_t arg_count, first_extra_arg;
@@ -474,29 +176,29 @@ ZEND_FUNCTION(func_get_arg)
zend_execute_data *ex;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &requested_offset) == FAILURE) {
- return;
+ RETURN_THROWS();
}
if (requested_offset < 0) {
- zend_error(E_WARNING, "func_get_arg(): The argument number should be >= 0");
- RETURN_FALSE;
+ zend_argument_value_error(1, "must be greater than or equal to 0");
+ RETURN_THROWS();
}
ex = EX(prev_execute_data);
if (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE) {
- zend_error(E_WARNING, "func_get_arg(): Called from the global scope - no function context");
- RETURN_FALSE;
+ zend_throw_error(NULL, "func_get_arg() cannot be called from the global scope");
+ RETURN_THROWS();
}
if (zend_forbid_dynamic_call("func_get_arg()") == FAILURE) {
- RETURN_FALSE;
+ RETURN_THROWS();
}
arg_count = ZEND_CALL_NUM_ARGS(ex);
if ((zend_ulong)requested_offset >= arg_count) {
- zend_error(E_WARNING, "func_get_arg(): Argument " ZEND_LONG_FMT " not passed to function", requested_offset);
- RETURN_FALSE;
+ zend_argument_value_error(1, "must be less than the number of the arguments passed to the currently executed function");
+ RETURN_THROWS();
}
first_extra_arg = ex->func->op_array.num_args;
@@ -511,8 +213,7 @@ ZEND_FUNCTION(func_get_arg)
}
/* }}} */
-/* {{{ proto array func_get_args()
- Get an array of the arguments that were passed to the function */
+/* {{{ Get an array of the arguments that were passed to the function */
ZEND_FUNCTION(func_get_args)
{
zval *p, *q;
@@ -520,13 +221,15 @@ ZEND_FUNCTION(func_get_args)
uint32_t i;
zend_execute_data *ex = EX(prev_execute_data);
+ ZEND_PARSE_PARAMETERS_NONE();
+
if (ZEND_CALL_INFO(ex) & ZEND_CALL_CODE) {
- zend_error(E_WARNING, "func_get_args(): Called from the global scope - no function context");
- RETURN_FALSE;
+ zend_throw_error(NULL, "func_get_args() cannot be called from the global scope");
+ RETURN_THROWS();
}
if (zend_forbid_dynamic_call("func_get_args()") == FAILURE) {
- RETURN_FALSE;
+ RETURN_THROWS();
}
arg_count = ZEND_CALL_NUM_ARGS(ex);
@@ -579,8 +282,7 @@ ZEND_FUNCTION(func_get_args)
}
/* }}} */
-/* {{{ proto int strlen(string str)
- Get string length
+/* {{{ Get string length
Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
ZEND_FUNCTION(strlen)
{
@@ -594,8 +296,7 @@ ZEND_FUNCTION(strlen)
}
/* }}} */
-/* {{{ proto int strcmp(string str1, string str2)
- Binary safe string comparison */
+/* {{{ Binary safe string comparison */
ZEND_FUNCTION(strcmp)
{
zend_string *s1, *s2;
@@ -609,8 +310,7 @@ ZEND_FUNCTION(strcmp)
}
/* }}} */
-/* {{{ proto int strncmp(string str1, string str2, int len)
- Binary safe string comparison */
+/* {{{ Binary safe string comparison */
ZEND_FUNCTION(strncmp)
{
zend_string *s1, *s2;
@@ -623,16 +323,15 @@ ZEND_FUNCTION(strncmp)
ZEND_PARSE_PARAMETERS_END();
if (len < 0) {
- zend_error(E_WARNING, "Length must be greater than or equal to 0");
- RETURN_FALSE;
+ zend_argument_value_error(3, "must be greater than or equal to 0");
+ RETURN_THROWS();
}
RETURN_LONG(zend_binary_strncmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2), len));
}
/* }}} */
-/* {{{ proto int strcasecmp(string str1, string str2)
- Binary safe case-insensitive string comparison */
+/* {{{ Binary safe case-insensitive string comparison */
ZEND_FUNCTION(strcasecmp)
{
zend_string *s1, *s2;
@@ -646,8 +345,7 @@ ZEND_FUNCTION(strcasecmp)
}
/* }}} */
-/* {{{ proto int strncasecmp(string str1, string str2, int len)
- Binary safe string comparison */
+/* {{{ Binary safe string comparison */
ZEND_FUNCTION(strncasecmp)
{
zend_string *s1, *s2;
@@ -660,92 +358,32 @@ ZEND_FUNCTION(strncasecmp)
ZEND_PARSE_PARAMETERS_END();
if (len < 0) {
- zend_error(E_WARNING, "Length must be greater than or equal to 0");
- RETURN_FALSE;
+ zend_argument_value_error(3, "must be greater than or equal to 0");
+ RETURN_THROWS();
}
RETURN_LONG(zend_binary_strncasecmp(ZSTR_VAL(s1), ZSTR_LEN(s1), ZSTR_VAL(s2), ZSTR_LEN(s2), len));
}
/* }}} */
-/* {{{ proto mixed each(array &arr)
- 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 */
-ZEND_FUNCTION(each)
-{
- zval *array, *entry, tmp;
- zend_ulong num_key;
- HashTable *target_hash;
- zend_string *key;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "z/", &array) == FAILURE) {
- return;
- }
-
- if (!EG(each_deprecation_thrown)) {
- zend_error(E_DEPRECATED, "The each() function is deprecated. This message will be suppressed on further calls");
- EG(each_deprecation_thrown) = 1;
- }
-
- target_hash = HASH_OF(array);
- if (!target_hash) {
- zend_error(E_WARNING,"Variable passed to each() is not an array or object");
- return;
- }
- while (1) {
- entry = zend_hash_get_current_data(target_hash);
- if (!entry) {
- RETURN_FALSE;
- } else if (Z_TYPE_P(entry) == IS_INDIRECT) {
- entry = Z_INDIRECT_P(entry);
- if (Z_TYPE_P(entry) == IS_UNDEF) {
- zend_hash_move_forward(target_hash);
- continue;
- }
- }
- break;
- }
- array_init_size(return_value, 4);
- zend_hash_real_init_mixed(Z_ARRVAL_P(return_value));
-
- /* add value elements */
- ZVAL_DEREF(entry);
- if (Z_REFCOUNTED_P(entry)) {
- GC_ADDREF_EX(Z_COUNTED_P(entry), 2);
- }
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), 1, entry);
- zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_VALUE), entry);
-
- /* add the key elements */
- if (zend_hash_get_current_key(target_hash, &key, &num_key) == HASH_KEY_IS_STRING) {
- ZVAL_STR_COPY(&tmp, key);
- Z_TRY_ADDREF(tmp);
- } else {
- ZVAL_LONG(&tmp, num_key);
- }
- zend_hash_index_add_new(Z_ARRVAL_P(return_value), 0, &tmp);
- zend_hash_add_new(Z_ARRVAL_P(return_value), ZSTR_KNOWN(ZEND_STR_KEY), &tmp);
- zend_hash_move_forward(target_hash);
-}
-/* }}} */
-
-/* {{{ proto int error_reporting([int new_error_level])
- Return the current error_reporting level, and if an argument was passed - change to the new level */
+/* {{{ Return the current error_reporting level, and if an argument was passed - change to the new level */
ZEND_FUNCTION(error_reporting)
{
- zval *err = NULL;
+ zend_long err;
+ zend_bool err_is_null = 1;
int old_error_reporting;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
- Z_PARAM_ZVAL(err)
+ Z_PARAM_LONG_OR_NULL(err, err_is_null)
ZEND_PARSE_PARAMETERS_END();
old_error_reporting = EG(error_reporting);
- if (ZEND_NUM_ARGS() != 0) {
- zend_string *new_val = zval_try_get_string(err);
+ if (!err_is_null) {
+ zend_string *new_val = zend_long_to_str(err);
if (UNEXPECTED(!new_val)) {
- return;
+ RETURN_THROWS();
}
do {
@@ -774,11 +412,7 @@ ZEND_FUNCTION(error_reporting)
}
p->value = new_val;
- if (Z_TYPE_P(err) == IS_LONG) {
- EG(error_reporting) = Z_LVAL_P(err);
- } else {
- EG(error_reporting) = atoi(ZSTR_VAL(p->value));
- }
+ EG(error_reporting) = err;
} while (0);
}
@@ -786,9 +420,9 @@ ZEND_FUNCTION(error_reporting)
}
/* }}} */
-static int validate_constant_array(HashTable *ht) /* {{{ */
+static bool validate_constant_array_argument(HashTable *ht, int argument_number) /* {{{ */
{
- int ret = 1;
+ bool ret = 1;
zval *val;
GC_PROTECT_RECURSION(ht);
@@ -798,16 +432,16 @@ static int validate_constant_array(HashTable *ht) /* {{{ */
if (Z_TYPE_P(val) == IS_ARRAY) {
if (Z_REFCOUNTED_P(val)) {
if (Z_IS_RECURSIVE_P(val)) {
- zend_error(E_WARNING, "Constants cannot be recursive arrays");
+ zend_argument_value_error(argument_number, "cannot be a recursive array");
ret = 0;
break;
- } else if (!validate_constant_array(Z_ARRVAL_P(val))) {
+ } else if (!validate_constant_array_argument(Z_ARRVAL_P(val), argument_number)) {
ret = 0;
break;
}
}
} else if (Z_TYPE_P(val) != IS_STRING && Z_TYPE_P(val) != IS_RESOURCE) {
- zend_error(E_WARNING, "Constants may only evaluate to scalar values, arrays or resources");
+ zend_argument_type_error(argument_number, "cannot be an object, %s given", zend_zval_type_name(val));
ret = 0;
break;
}
@@ -844,14 +478,12 @@ static void copy_constant_array(zval *dst, zval *src) /* {{{ */
}
/* }}} */
-/* {{{ proto bool define(string constant_name, mixed value[, bool case_insensitive])
- Define a new constant */
+/* {{{ Define a new constant */
ZEND_FUNCTION(define)
{
zend_string *name;
zval *val, val_free;
zend_bool non_cs = 0;
- int case_sensitive = CONST_CS;
zend_constant c;
ZEND_PARSE_PARAMETERS_START(2, 3)
@@ -861,18 +493,17 @@ ZEND_FUNCTION(define)
Z_PARAM_BOOL(non_cs)
ZEND_PARSE_PARAMETERS_END();
- if (non_cs) {
- case_sensitive = 0;
- }
-
if (zend_memnstr(ZSTR_VAL(name), "::", sizeof("::") - 1, ZSTR_VAL(name) + ZSTR_LEN(name))) {
- zend_error(E_WARNING, "Class constants cannot be defined or redefined");
- RETURN_FALSE;
+ zend_argument_value_error(1, "cannot be a class constant");
+ RETURN_THROWS();
}
+ if (non_cs) {
+ zend_error(E_WARNING, "define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported");
+ }
+
ZVAL_UNDEF(&val_free);
-repeat:
switch (Z_TYPE_P(val)) {
case IS_LONG:
case IS_DOUBLE:
@@ -884,8 +515,8 @@ repeat:
break;
case IS_ARRAY:
if (Z_REFCOUNTED_P(val)) {
- if (!validate_constant_array(Z_ARRVAL_P(val))) {
- RETURN_FALSE;
+ if (!validate_constant_array_argument(Z_ARRVAL_P(val), 2)) {
+ RETURN_THROWS();
} else {
copy_constant_array(&c.value, val);
goto register_constant;
@@ -893,35 +524,23 @@ repeat:
}
break;
case IS_OBJECT:
- if (Z_TYPE(val_free) == IS_UNDEF) {
- if (Z_OBJ_HT_P(val)->get) {
- val = Z_OBJ_HT_P(val)->get(val, &val_free);
- goto repeat;
- } else if (Z_OBJ_HT_P(val)->cast_object) {
- if (Z_OBJ_HT_P(val)->cast_object(val, &val_free, IS_STRING) == SUCCESS) {
- val = &val_free;
- break;
- }
- }
+ if (Z_OBJ_HT_P(val)->cast_object(Z_OBJ_P(val), &val_free, IS_STRING) == SUCCESS) {
+ val = &val_free;
+ break;
}
/* no break */
default:
- zend_error(E_WARNING, "Constants may only evaluate to scalar values, arrays or resources");
zval_ptr_dtor(&val_free);
- RETURN_FALSE;
+ zend_argument_type_error(2, "cannot be an object, %s given", zend_zval_type_name(val));
+ RETURN_THROWS();
}
ZVAL_COPY(&c.value, val);
zval_ptr_dtor(&val_free);
register_constant:
- if (non_cs) {
- zend_error(E_DEPRECATED,
- "define(): Declaration of case-insensitive constants is deprecated");
- }
-
/* non persistent */
- ZEND_CONSTANT_SET_FLAGS(&c, case_sensitive, PHP_USER_CONSTANT);
+ ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, PHP_USER_CONSTANT);
c.name = zend_string_copy(name);
if (zend_register_constant(&c) == SUCCESS) {
RETURN_TRUE;
@@ -931,8 +550,7 @@ register_constant:
}
/* }}} */
-/* {{{ proto bool defined(string constant_name)
- Check whether a constant exists
+/* {{{ Check whether a constant exists
Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
ZEND_FUNCTION(defined)
{
@@ -942,7 +560,7 @@ ZEND_FUNCTION(defined)
Z_PARAM_STR(name)
ZEND_PARSE_PARAMETERS_END();
- if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT | ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) {
+ if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) {
RETURN_TRUE;
} else {
RETURN_FALSE;
@@ -950,14 +568,13 @@ ZEND_FUNCTION(defined)
}
/* }}} */
-/* {{{ proto string get_class([object object])
- Retrieves the class name */
+/* {{{ Retrieves the class name */
ZEND_FUNCTION(get_class)
{
zval *obj = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o", &obj) == FAILURE) {
- RETURN_FALSE;
+ RETURN_THROWS();
}
if (!obj) {
@@ -966,8 +583,8 @@ ZEND_FUNCTION(get_class)
if (scope) {
RETURN_STR_COPY(scope->name);
} else {
- zend_error(E_WARNING, "get_class() called without object from outside a class");
- RETURN_FALSE;
+ zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
+ RETURN_THROWS();
}
}
@@ -975,53 +592,35 @@ ZEND_FUNCTION(get_class)
}
/* }}} */
-/* {{{ proto string get_called_class()
- Retrieves the "Late Static Binding" class name */
+/* {{{ Retrieves the "Late Static Binding" class name */
ZEND_FUNCTION(get_called_class)
{
zend_class_entry *called_scope;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
called_scope = zend_get_called_scope(execute_data);
- if (called_scope) {
- RETURN_STR_COPY(called_scope->name);
- } else {
- zend_class_entry *scope = zend_get_executed_scope();
- if (!scope) {
- zend_error(E_WARNING, "get_called_class() called from outside a class");
- }
+ if (!called_scope) {
+ zend_throw_error(NULL, "get_called_class() must be called from within a class");
+ RETURN_THROWS();
}
- RETURN_FALSE;
+
+ RETURN_STR_COPY(called_scope->name);
}
/* }}} */
-/* {{{ proto mixed get_parent_class([mixed object])
- Retrieves the parent class name for object or class or current scope or false if not in a scope. */
+/* {{{ Retrieves the parent class name for object or class or current scope or false if not in a scope. */
ZEND_FUNCTION(get_parent_class)
{
- zval *arg;
zend_class_entry *ce = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &arg) == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_START(0, 1)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_OBJ_OR_CLASS_NAME(ce)
+ ZEND_PARSE_PARAMETERS_END();
- if (!ZEND_NUM_ARGS()) {
+ if (!ce) {
ce = zend_get_executed_scope();
- if (ce && ce->parent) {
- RETURN_STR_COPY(ce->parent->name);
- } else {
- RETURN_FALSE;
- }
- }
-
- if (Z_TYPE_P(arg) == IS_OBJECT) {
- ce = Z_OBJ_P(arg)->ce;
- } else if (Z_TYPE_P(arg) == IS_STRING) {
- ce = zend_lookup_class(Z_STR_P(arg));
}
if (ce && ce->parent) {
@@ -1084,16 +683,14 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) /*
}
/* }}} */
-/* {{{ proto bool is_subclass_of(mixed object_or_string, string class_name [, bool allow_string])
- Returns true if the object has this class as one of its parents */
+/* {{{ Returns true if the object has this class as one of its parents */
ZEND_FUNCTION(is_subclass_of)
{
is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
/* }}} */
-/* {{{ proto bool is_a(mixed object_or_string, string class_name [, bool allow_string])
- Returns true if the first argument is an object and is this class or has this class as one of its parents, */
+/* {{{ Returns true if the first argument is an object and is this class or has this class as one of its parents, */
ZEND_FUNCTION(is_a)
{
is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
@@ -1101,7 +698,7 @@ ZEND_FUNCTION(is_a)
/* }}} */
/* {{{ add_class_vars */
-static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int statics, zval *return_value)
+static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, bool statics, zval *return_value)
{
zend_property_info *prop_info;
zval *prop, prop_copy;
@@ -1147,36 +744,29 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st
}
/* }}} */
-/* {{{ proto array get_class_vars(string class_name)
- Returns an array of default properties of the class. */
+/* {{{ Returns an array of default properties of the class. */
ZEND_FUNCTION(get_class_vars)
{
- zend_string *class_name;
- zend_class_entry *ce, *scope;
+ zend_class_entry *ce = NULL, *scope;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &class_name) == FAILURE) {
- return;
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "C", &ce) == FAILURE) {
+ RETURN_THROWS();
}
- ce = zend_lookup_class(class_name);
- if (!ce) {
- RETURN_FALSE;
- } else {
- array_init(return_value);
- if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
- if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
- return;
- }
+ array_init(return_value);
+ if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED))) {
+ if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
+ return;
}
- scope = zend_get_executed_scope();
- add_class_vars(scope, ce, 0, return_value);
- add_class_vars(scope, ce, 1, return_value);
}
+
+ scope = zend_get_executed_scope();
+ add_class_vars(scope, ce, 0, return_value);
+ add_class_vars(scope, ce, 1, return_value);
}
/* }}} */
-/* {{{ proto array get_object_vars(object obj)
- Returns an array of object properties */
+/* {{{ Returns an array of object properties */
ZEND_FUNCTION(get_object_vars)
{
zval *obj;
@@ -1190,13 +780,12 @@ ZEND_FUNCTION(get_object_vars)
Z_PARAM_OBJECT(obj)
ZEND_PARSE_PARAMETERS_END();
- properties = Z_OBJ_HT_P(obj)->get_properties(obj);
+ zobj = Z_OBJ_P(obj);
+ properties = zobj->handlers->get_properties(zobj);
if (properties == NULL) {
- RETURN_FALSE;
+ RETURN_EMPTY_ARRAY();
}
- zobj = Z_OBJ_P(obj);
-
if (!zobj->ce->default_properties_count && properties == zobj->properties && !GC_IS_RECURSIVE(properties)) {
/* fast copy */
if (EXPECTED(zobj->handlers == &std_object_handlers)) {
@@ -1247,8 +836,7 @@ ZEND_FUNCTION(get_object_vars)
}
/* }}} */
-/* {{{ proto array get_mangled_object_vars(object obj)
- Returns an array of mangled object properties. Does not respect property visibility. */
+/* {{{ Returns an array of mangled object properties. Does not respect property visibility. */
ZEND_FUNCTION(get_mangled_object_vars)
{
zval *obj;
@@ -1258,7 +846,7 @@ ZEND_FUNCTION(get_mangled_object_vars)
Z_PARAM_OBJECT(obj)
ZEND_PARSE_PARAMETERS_END();
- properties = Z_OBJ_HT_P(obj)->get_properties(obj);
+ properties = Z_OBJ_HT_P(obj)->get_properties(Z_OBJ_P(obj));
if (!properties) {
ZVAL_EMPTY_ARRAY(return_value);
return;
@@ -1272,10 +860,10 @@ ZEND_FUNCTION(get_mangled_object_vars)
}
/* }}} */
-static int same_name(zend_string *key, zend_string *name) /* {{{ */
+static bool same_name(zend_string *key, zend_string *name) /* {{{ */
{
zend_string *lcname;
- int ret;
+ bool ret;
if (key == name) {
return 1;
@@ -1290,36 +878,22 @@ static int same_name(zend_string *key, zend_string *name) /* {{{ */
}
/* }}} */
-/* {{{ proto array get_class_methods(mixed class)
- Returns an array of method names for class or class instance. */
+/* {{{ Returns an array of method names for class or class instance. */
ZEND_FUNCTION(get_class_methods)
{
- zval *klass;
zval method_name;
zend_class_entry *ce = NULL;
zend_class_entry *scope;
zend_function *mptr;
- zend_string *key;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &klass) == FAILURE) {
- return;
- }
-
- if (Z_TYPE_P(klass) == IS_OBJECT) {
- ce = Z_OBJCE_P(klass);
- } else if (Z_TYPE_P(klass) == IS_STRING) {
- ce = zend_lookup_class(Z_STR_P(klass));
- }
-
- if (!ce) {
- RETURN_NULL();
- }
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_OBJ_OR_CLASS_NAME(ce)
+ ZEND_PARSE_PARAMETERS_END();
array_init(return_value);
scope = zend_get_executed_scope();
- ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) {
-
+ ZEND_HASH_FOREACH_PTR(&ce->function_table, mptr) {
if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC)
|| (scope &&
(((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
@@ -1327,22 +901,14 @@ ZEND_FUNCTION(get_class_methods)
|| ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
scope == mptr->common.scope)))
) {
- if (mptr->type == ZEND_USER_FUNCTION &&
- (!mptr->op_array.refcount || *mptr->op_array.refcount > 1) &&
- key && !same_name(key, mptr->common.function_name)) {
- ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key));
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
- } else {
- ZVAL_STR_COPY(&method_name, mptr->common.function_name);
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
- }
+ ZVAL_STR_COPY(&method_name, mptr->common.function_name);
+ zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name);
}
} ZEND_HASH_FOREACH_END();
}
/* }}} */
-/* {{{ proto bool method_exists(object object, string method)
- Checks if the class method exists */
+/* {{{ Checks if the class method exists */
ZEND_FUNCTION(method_exists)
{
zval *klass;
@@ -1363,7 +929,8 @@ ZEND_FUNCTION(method_exists)
RETURN_FALSE;
}
} else {
- RETURN_FALSE;
+ zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_type_name(klass));
+ RETURN_THROWS();
}
lcname = zend_string_tolower(method_name);
@@ -1398,22 +965,16 @@ ZEND_FUNCTION(method_exists)
}
/* }}} */
-/* {{{ proto bool property_exists(mixed object_or_class, string property_name)
- Checks if the object or class has a property */
+/* {{{ Checks if the object or class has a property */
ZEND_FUNCTION(property_exists)
{
zval *object;
zend_string *property;
zend_class_entry *ce;
zend_property_info *property_info;
- zval property_z;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zS", &object, &property) == FAILURE) {
- return;
- }
-
- if (property == NULL) {
- RETURN_FALSE;
+ RETURN_THROWS();
}
if (Z_TYPE_P(object) == IS_STRING) {
@@ -1424,8 +985,8 @@ ZEND_FUNCTION(property_exists)
} else if (Z_TYPE_P(object) == IS_OBJECT) {
ce = Z_OBJCE_P(object);
} else {
- zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
- RETURN_NULL();
+ zend_argument_type_error(1, "must be of type object|string, %s given", zend_zval_type_name(object));
+ RETURN_THROWS();
}
property_info = zend_hash_find_ptr(&ce->properties_info, property);
@@ -1435,10 +996,8 @@ ZEND_FUNCTION(property_exists)
RETURN_TRUE;
}
- ZVAL_STR(&property_z, property);
-
if (Z_TYPE_P(object) == IS_OBJECT &&
- Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, NULL)) {
+ Z_OBJ_HANDLER_P(object, has_property)(Z_OBJ_P(object), property, 2, NULL)) {
RETURN_TRUE;
}
RETURN_FALSE;
@@ -1481,36 +1040,32 @@ static inline void class_exists_impl(INTERNAL_FUNCTION_PARAMETERS, int flags, in
}
/* {{{ */
-/* {{{ proto bool class_exists(string classname [, bool autoload])
- Checks if the class exists */
+/* {{{ Checks if the class exists */
ZEND_FUNCTION(class_exists)
{
class_exists_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_LINKED, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
}
/* }}} */
-/* {{{ proto bool interface_exists(string classname [, bool autoload])
- Checks if the class exists */
+/* {{{ Checks if the class exists */
ZEND_FUNCTION(interface_exists)
{
class_exists_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_LINKED|ZEND_ACC_INTERFACE, 0);
}
/* }}} */
-/* {{{ proto bool trait_exists(string traitname [, bool autoload])
- Checks if the trait exists */
+/* {{{ Checks if the trait exists */
ZEND_FUNCTION(trait_exists)
{
class_exists_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT, 0);
}
/* }}} */
-/* {{{ proto bool function_exists(string function_name)
- Checks if the function exists */
+/* {{{ Checks if the function exists */
ZEND_FUNCTION(function_exists)
{
zend_string *name;
- zend_function *func;
+ zend_bool exists;
zend_string *lcname;
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -1525,20 +1080,14 @@ ZEND_FUNCTION(function_exists)
lcname = zend_string_tolower(name);
}
- func = zend_hash_find_ptr(EG(function_table), lcname);
+ exists = zend_hash_exists(EG(function_table), lcname);
zend_string_release_ex(lcname, 0);
- /*
- * A bit of a hack, but not a bad one: we see if the handler of the function
- * is actually one that displays "function is disabled" message.
- */
- RETURN_BOOL(func && (func->type != ZEND_INTERNAL_FUNCTION ||
- func->internal_function.handler != zif_display_disabled_function));
+ RETURN_BOOL(exists);
}
/* }}} */
-/* {{{ proto bool class_alias(string user_class_name , string alias_name [, bool autoload])
- Creates an alias for user defined class */
+/* {{{ Creates an alias for user defined class */
ZEND_FUNCTION(class_alias)
{
zend_string *class_name;
@@ -1548,7 +1097,7 @@ ZEND_FUNCTION(class_alias)
zend_bool autoload = 1;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ss|b", &class_name, &alias_name, &alias_name_len, &autoload) == FAILURE) {
- return;
+ RETURN_THROWS();
}
ce = zend_lookup_class_ex(class_name, NULL, !autoload ? ZEND_FETCH_CLASS_NO_AUTOLOAD : 0);
@@ -1562,25 +1111,22 @@ ZEND_FUNCTION(class_alias)
RETURN_FALSE;
}
} else {
- zend_error(E_WARNING, "First argument of class_alias() must be a name of user defined class");
- RETURN_FALSE;
+ zend_argument_value_error(1, "must be a user-defined class name, internal class name given");
+ RETURN_THROWS();
}
} else {
- zend_error(E_WARNING, "Class '%s' not found", ZSTR_VAL(class_name));
+ zend_error(E_WARNING, "Class \"%s\" not found", ZSTR_VAL(class_name));
RETURN_FALSE;
}
}
/* }}} */
-/* {{{ proto array get_included_files(void)
- Returns an array with the file names that were include_once()'d */
+/* {{{ Returns an array with the file names that were include_once()'d */
ZEND_FUNCTION(get_included_files)
{
zend_string *entry;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
array_init(return_value);
ZEND_HASH_FOREACH_STR_KEY(&EG(included_files), entry) {
@@ -1591,8 +1137,7 @@ ZEND_FUNCTION(get_included_files)
}
/* }}} */
-/* {{{ proto void trigger_error(string message [, int error_type])
- Generates a user-level error/warning/notice message */
+/* {{{ Generates a user-level error/warning/notice message */
ZEND_FUNCTION(trigger_error)
{
zend_long error_type = E_USER_NOTICE;
@@ -1600,7 +1145,7 @@ ZEND_FUNCTION(trigger_error)
size_t message_len;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &message, &message_len, &error_type) == FAILURE) {
- return;
+ RETURN_THROWS();
}
switch (error_type) {
@@ -1610,35 +1155,28 @@ ZEND_FUNCTION(trigger_error)
case E_USER_DEPRECATED:
break;
default:
- zend_error(E_WARNING, "Invalid error type specified");
- RETURN_FALSE;
+ zend_argument_value_error(2, "must be one of E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE,"
+ " or E_USER_DEPRECATED");
+ RETURN_THROWS();
break;
}
zend_error((int)error_type, "%s", message);
+ // TODO Change to void
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto string set_error_handler(callable error_handler [, int error_types])
- Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */
+/* {{{ Sets a user-defined error handler function. Returns the previously defined error handler, or false on error */
ZEND_FUNCTION(set_error_handler)
{
- zval *error_handler;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
zend_long error_type = E_ALL;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|l", &error_handler, &error_type) == FAILURE) {
- return;
- }
-
- if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */
- if (!zend_is_callable(error_handler, 0, NULL)) {
- zend_string *error_handler_name = zend_get_callable_name(error_handler);
- zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
- get_active_function_name(), error_handler_name?ZSTR_VAL(error_handler_name):"unknown");
- zend_string_release_ex(error_handler_name, 0);
- return;
- }
+ /* callable argument corresponds to the error handler */
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "f!|l", &fci, &fcc, &error_type) == FAILURE) {
+ RETURN_THROWS();
}
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
@@ -1648,23 +1186,20 @@ ZEND_FUNCTION(set_error_handler)
zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
- if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
+ if (!ZEND_FCI_INITIALIZED(fci)) { /* unset user-defined handler */
ZVAL_UNDEF(&EG(user_error_handler));
return;
}
- ZVAL_COPY(&EG(user_error_handler), error_handler);
+ ZVAL_COPY(&EG(user_error_handler), &(fci.function_name));
EG(user_error_handler_error_reporting) = (int)error_type;
}
/* }}} */
-/* {{{ proto void restore_error_handler(void)
- Restores the previously defined error handler function */
+/* {{{ Restores the previously defined error handler function */
ZEND_FUNCTION(restore_error_handler)
{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
zval zeh;
@@ -1684,28 +1219,21 @@ ZEND_FUNCTION(restore_error_handler)
ZVAL_COPY_VALUE(&EG(user_error_handler), tmp);
zend_stack_del_top(&EG(user_error_handlers));
}
+
+ // TODO Change to void
RETURN_TRUE;
}
/* }}} */
-/* {{{ proto mixed set_exception_handler(callable exception_handler)
- Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */
+/* {{{ Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */
ZEND_FUNCTION(set_exception_handler)
{
- zval *exception_handler;
+ zend_fcall_info fci;
+ zend_fcall_info_cache fcc;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &exception_handler) == FAILURE) {
- return;
- }
-
- if (Z_TYPE_P(exception_handler) != IS_NULL) { /* NULL == unset */
- if (!zend_is_callable(exception_handler, 0, NULL)) {
- zend_string *exception_handler_name = zend_get_callable_name(exception_handler);
- zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
- get_active_function_name(), exception_handler_name?ZSTR_VAL(exception_handler_name):"unknown");
- zend_string_release_ex(exception_handler_name, 0);
- return;
- }
+ /* callable argument corresponds to the exception handler */
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "f!", &fci, &fcc) == FAILURE) {
+ RETURN_THROWS();
}
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
@@ -1714,22 +1242,19 @@ ZEND_FUNCTION(set_exception_handler)
zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
- if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
+ if (!ZEND_FCI_INITIALIZED(fci)) { /* unset user-defined handler */
ZVAL_UNDEF(&EG(user_exception_handler));
return;
}
- ZVAL_COPY(&EG(user_exception_handler), exception_handler);
+ ZVAL_COPY(&EG(user_exception_handler), &(fci.function_name));
}
/* }}} */
-/* {{{ proto void restore_exception_handler(void)
- Restores the previously defined exception handler function */
+/* {{{ Restores the previously defined exception handler function */
ZEND_FUNCTION(restore_exception_handler)
{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
zval_ptr_dtor(&EG(user_exception_handler));
@@ -1741,6 +1266,8 @@ ZEND_FUNCTION(restore_exception_handler)
ZVAL_COPY_VALUE(&EG(user_exception_handler), tmp);
zend_stack_del_top(&EG(user_exception_handlers));
}
+
+ // TODO Change to void
RETURN_TRUE;
}
/* }}} */
@@ -1760,9 +1287,7 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla
zend_string *key;
zend_class_entry *ce;
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
+ ZEND_PARSE_PARAMETERS_NONE();
array_init(return_value);
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) {
@@ -1776,41 +1301,42 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla
}
/* {{{ */
-/* {{{ proto array get_declared_traits()
- Returns an array of all declared traits. */
+/* {{{ Returns an array of all declared traits. */
ZEND_FUNCTION(get_declared_traits)
{
get_declared_class_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT, 0);
}
/* }}} */
-/* {{{ proto array get_declared_classes()
- Returns an array of all declared classes. */
+/* {{{ Returns an array of all declared classes. */
ZEND_FUNCTION(get_declared_classes)
{
get_declared_class_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_LINKED, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
}
/* }}} */
-/* {{{ proto array get_declared_interfaces()
- Returns an array of all declared interfaces. */
+/* {{{ Returns an array of all declared interfaces. */
ZEND_FUNCTION(get_declared_interfaces)
{
get_declared_class_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE, 0);
}
/* }}} */
-/* {{{ proto array get_defined_functions(void)
- Returns an array of all defined functions */
+/* {{{ Returns an array of all defined functions */
ZEND_FUNCTION(get_defined_functions)
{
zval internal, user;
zend_string *key;
zend_function *func;
- zend_bool exclude_disabled = 0;
+ zend_bool exclude_disabled = 1;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &exclude_disabled) == FAILURE) {
- return;
+ RETURN_THROWS();
+ }
+
+ if (exclude_disabled == 0) {
+ zend_error(E_DEPRECATED,
+ "get_defined_functions(): Setting $exclude_disabled to false has no effect");
}
array_init(&internal);
@@ -1819,8 +1345,7 @@ ZEND_FUNCTION(get_defined_functions)
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(function_table), key, func) {
if (key && ZSTR_VAL(key)[0] != 0) {
- if (func->type == ZEND_INTERNAL_FUNCTION
- && (!exclude_disabled || func->internal_function.handler != ZEND_FN(display_disabled_function))) {
+ if (func->type == ZEND_INTERNAL_FUNCTION) {
add_next_index_str(&internal, zend_string_copy(key));
} else if (func->type == ZEND_USER_FUNCTION) {
add_next_index_str(&user, zend_string_copy(key));
@@ -1833,112 +1358,43 @@ ZEND_FUNCTION(get_defined_functions)
}
/* }}} */
-/* {{{ proto array get_defined_vars(void)
- Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
+/* {{{ Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
ZEND_FUNCTION(get_defined_vars)
{
zend_array *symbol_table;
+
+ ZEND_PARSE_PARAMETERS_NONE();
+
if (zend_forbid_dynamic_call("get_defined_vars()") == FAILURE) {
return;
}
symbol_table = zend_rebuild_symbol_table();
if (UNEXPECTED(symbol_table == NULL)) {
- return;
+ RETURN_EMPTY_ARRAY();
}
RETURN_ARR(zend_array_dup(symbol_table));
}
/* }}} */
-#define LAMBDA_TEMP_FUNCNAME "__lambda_func"
-/* {{{ proto string create_function(string args, string code)
- Creates an anonymous function, and returns its name (funny, eh?) */
-ZEND_FUNCTION(create_function)
-{
- zend_string *function_name;
- char *eval_code, *function_args, *function_code;
- size_t eval_code_length, function_args_len, function_code_len;
- int retval;
- char *eval_name;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &function_args, &function_args_len, &function_code, &function_code_len) == FAILURE) {
- return;
- }
-
- eval_code = (char *) emalloc(sizeof("function " LAMBDA_TEMP_FUNCNAME)
- +function_args_len
- +2 /* for the args parentheses */
- +2 /* for the curly braces */
- +function_code_len);
-
- eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME "(") - 1;
- memcpy(eval_code, "function " LAMBDA_TEMP_FUNCNAME "(", eval_code_length);
-
- memcpy(eval_code + eval_code_length, function_args, function_args_len);
- eval_code_length += function_args_len;
-
- eval_code[eval_code_length++] = ')';
- eval_code[eval_code_length++] = '{';
-
- memcpy(eval_code + eval_code_length, function_code, function_code_len);
- eval_code_length += function_code_len;
-
- eval_code[eval_code_length++] = '}';
- eval_code[eval_code_length] = '\0';
-
- eval_name = zend_make_compiled_string_description("runtime-created function");
- retval = zend_eval_stringl(eval_code, eval_code_length, NULL, eval_name);
- efree(eval_code);
- efree(eval_name);
-
- if (retval==SUCCESS) {
- zend_op_array *func;
- HashTable *static_variables;
-
- func = zend_hash_str_find_ptr(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
- if (!func) {
- zend_error_noreturn(E_CORE_ERROR, "Unexpected inconsistency in create_function()");
- RETURN_FALSE;
- }
- if (func->refcount) {
- (*func->refcount)++;
- }
- static_variables = func->static_variables;
- func->static_variables = NULL;
- zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
- func->static_variables = static_variables;
-
- function_name = zend_string_alloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG, 0);
- ZSTR_VAL(function_name)[0] = '\0';
-
- do {
- ZSTR_LEN(function_name) = snprintf(ZSTR_VAL(function_name) + 1, sizeof("lambda_")+MAX_LENGTH_OF_LONG, "lambda_%d", ++EG(lambda_count)) + 1;
- } while (zend_hash_add_ptr(EG(function_table), function_name, func) == NULL);
- RETURN_NEW_STR(function_name);
- } else {
- zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1);
- RETURN_FALSE;
- }
-}
-/* }}} */
-
#if ZEND_DEBUG && defined(ZTS)
ZEND_FUNCTION(zend_thread_id)
{
+ ZEND_PARSE_PARAMETERS_NONE();
+
RETURN_LONG((zend_long)tsrm_thread_id());
}
#endif
-/* {{{ proto string get_resource_type(resource res)
- Get the resource type name for a given resource */
+/* {{{ Get the resource type name for a given resource */
ZEND_FUNCTION(get_resource_type)
{
const char *resource_type;
zval *z_resource_type;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_resource_type) == FAILURE) {
- return;
+ RETURN_THROWS();
}
resource_type = zend_rsrc_list_get_rsrc_type(Z_RES_P(z_resource_type));
@@ -1950,8 +1406,20 @@ ZEND_FUNCTION(get_resource_type)
}
/* }}} */
-/* {{{ proto array get_resources([string resouce_type])
- Get an array with all active resources */
+/* {{{ Get the resource ID for a given resource */
+ZEND_FUNCTION(get_resource_id)
+{
+ zval *resource;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_RESOURCE(resource)
+ ZEND_PARSE_PARAMETERS_END();
+
+ RETURN_LONG(Z_RES_HANDLE_P(resource));
+}
+/* }}} */
+
+/* {{{ Get an array with all active resources */
ZEND_FUNCTION(get_resources)
{
zend_string *type = NULL;
@@ -1959,8 +1427,8 @@ ZEND_FUNCTION(get_resources)
zend_ulong index;
zval *val;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S", &type) == FAILURE) {
- return;
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &type) == FAILURE) {
+ RETURN_THROWS();
}
if (!type) {
@@ -1983,8 +1451,8 @@ ZEND_FUNCTION(get_resources)
int id = zend_fetch_list_dtor_id(ZSTR_VAL(type));
if (id <= 0) {
- zend_error(E_WARNING, "get_resources(): Unknown resource type '%s'", ZSTR_VAL(type));
- RETURN_FALSE;
+ zend_argument_value_error(1, "must be a valid resource type");
+ RETURN_THROWS();
}
array_init(return_value);
@@ -1998,28 +1466,26 @@ ZEND_FUNCTION(get_resources)
}
/* }}} */
-static int add_zendext_info(zend_extension *ext, void *arg) /* {{{ */
+static void add_zendext_info(zend_extension *ext, void *arg) /* {{{ */
{
zval *name_array = (zval *)arg;
add_next_index_string(name_array, ext->name);
- return 0;
}
/* }}} */
-/* {{{ proto array get_loaded_extensions([bool zend_extensions])
- Return an array containing names of loaded extensions */
+/* {{{ Return an array containing names of loaded extensions */
ZEND_FUNCTION(get_loaded_extensions)
{
zend_bool zendext = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &zendext) == FAILURE) {
- return;
+ RETURN_THROWS();
}
array_init(return_value);
if (zendext) {
- zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t)add_zendext_info, return_value);
+ zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) add_zendext_info, return_value);
} else {
zend_module_entry *module;
@@ -2030,14 +1496,13 @@ ZEND_FUNCTION(get_loaded_extensions)
}
/* }}} */
-/* {{{ proto array get_defined_constants([bool categorize])
- Return an array containing the names and values of all defined constants */
+/* {{{ Return an array containing the names and values of all defined constants */
ZEND_FUNCTION(get_defined_constants)
{
zend_bool categorize = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &categorize) == FAILURE) {
- return;
+ RETURN_THROWS();
}
array_init(return_value);
@@ -2121,16 +1586,12 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
* and we have to access them through symbol_table
* See: https://bugs.php.net/bug.php?id=73156
*/
- zend_string *arg_name;
- zval *arg;
-
while (i < first_extra_arg) {
- arg_name = call->func->op_array.vars[i];
- arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1);
+ zend_string *arg_name = call->func->op_array.vars[i];
+ zval *arg = zend_hash_find_ex_ind(call->symbol_table, arg_name, 1);
if (arg) {
- if (Z_OPT_REFCOUNTED_P(arg)) {
- Z_ADDREF_P(arg);
- }
+ ZVAL_DEREF(arg);
+ Z_TRY_ADDREF_P(arg);
ZEND_HASH_FILL_SET(arg);
} else {
ZEND_HASH_FILL_SET_NULL();
@@ -2141,10 +1602,10 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
} else {
while (i < first_extra_arg) {
if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
- if (Z_OPT_REFCOUNTED_P(p)) {
- Z_ADDREF_P(p);
- }
- ZEND_HASH_FILL_SET(p);
+ zval *arg = p;
+ ZVAL_DEREF(arg);
+ Z_TRY_ADDREF_P(arg);
+ ZEND_HASH_FILL_SET(arg);
} else {
ZEND_HASH_FILL_SET_NULL();
}
@@ -2158,10 +1619,10 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
while (i < num_args) {
if (EXPECTED(Z_TYPE_INFO_P(p) != IS_UNDEF)) {
- if (Z_OPT_REFCOUNTED_P(p)) {
- Z_ADDREF_P(p);
- }
- ZEND_HASH_FILL_SET(p);
+ zval *arg = p;
+ ZVAL_DEREF(arg);
+ Z_TRY_ADDREF_P(arg);
+ ZEND_HASH_FILL_SET(arg);
} else {
ZEND_HASH_FILL_SET_NULL();
}
@@ -2174,18 +1635,34 @@ static void debug_backtrace_get_args(zend_execute_data *call, zval *arg_array) /
} else {
ZVAL_EMPTY_ARRAY(arg_array);
}
+
+ if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
+ zend_string *name;
+ zval *arg;
+ SEPARATE_ARRAY(arg_array);
+ ZEND_HASH_FOREACH_STR_KEY_VAL(call->extra_named_params, name, arg) {
+ ZVAL_DEREF(arg);
+ Z_TRY_ADDREF_P(arg);
+ zend_hash_add_new(Z_ARRVAL_P(arg_array), name, arg);
+ } ZEND_HASH_FOREACH_END();
+ }
}
/* }}} */
void debug_print_backtrace_args(zval *arg_array) /* {{{ */
{
+ zend_string *name;
zval *tmp;
int i = 0;
- ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arg_array), tmp) {
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(arg_array), name, tmp) {
if (i++) {
ZEND_PUTS(", ");
}
+ if (name) {
+ ZEND_PUTS(ZSTR_VAL(name));
+ ZEND_PUTS(": ");
+ }
zend_print_flat_zval_r(tmp);
} ZEND_HASH_FOREACH_END();
}
@@ -2205,7 +1682,7 @@ static inline zend_bool skip_internal_handler(zend_execute_data *skip) /* {{{ */
}
/* {{{ */
-/* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
+/* {{{ */
ZEND_FUNCTION(debug_print_backtrace)
{
zend_execute_data *call, *ptr, *skip;
@@ -2223,7 +1700,7 @@ ZEND_FUNCTION(debug_print_backtrace)
zend_long limit = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &options, &limit) == FAILURE) {
- return;
+ RETURN_THROWS();
}
ZVAL_UNDEF(&arg_array);
@@ -2267,16 +1744,9 @@ ZEND_FUNCTION(debug_print_backtrace)
object = (Z_TYPE(call->This) == IS_OBJECT) ? Z_OBJ(call->This) : NULL;
if (call->func) {
- zend_string *zend_function_name;
-
func = call->func;
- if (func->common.scope && func->common.scope->trait_aliases) {
- zend_function_name = zend_resolve_method_name(object ? object->ce : func->common.scope, func);
- } else {
- zend_function_name = func->common.function_name;
- }
- if (zend_function_name != NULL) {
- function_name = ZSTR_VAL(zend_function_name);
+ if (func->common.function_name) {
+ function_name = ZSTR_VAL(func->common.function_name);
} else {
function_name = NULL;
}
@@ -2311,13 +1781,12 @@ ZEND_FUNCTION(debug_print_backtrace)
} else {
/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
zend_bool build_filename_arg = 1;
+ uint32_t include_kind = 0;
+ if (ptr->func && ZEND_USER_CODE(ptr->func->common.type) && ptr->opline->opcode == ZEND_INCLUDE_OR_EVAL) {
+ include_kind = ptr->opline->extended_value;
+ }
- if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
- /* can happen when calling eval from a custom sapi */
- function_name = "unknown";
- build_filename_arg = 0;
- } else
- switch (ptr->opline->extended_value) {
+ switch (include_kind) {
case ZEND_EVAL:
function_name = "eval";
build_filename_arg = 0;
@@ -2335,8 +1804,11 @@ ZEND_FUNCTION(debug_print_backtrace)
function_name = "require_once";
break;
default:
- /* this can actually happen if you use debug_backtrace() in your error_handler and
- * you're in the top-scope */
+ /* Skip dummy frame unless it is needed to preserve filename/lineno info. */
+ if (!filename) {
+ goto skip_frame;
+ }
+
function_name = "unknown";
build_filename_arg = 0;
break;
@@ -2387,10 +1859,12 @@ ZEND_FUNCTION(debug_print_backtrace)
ZEND_PUTS(")\n");
}
}
+ ++indent;
+
+skip_frame:
include_filename = filename;
call = skip;
ptr = skip->prev_execute_data;
- ++indent;
}
}
@@ -2496,11 +1970,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
if (call && call->func) {
func = call->func;
- function_name = (func->common.scope &&
- func->common.scope->trait_aliases) ?
- zend_resolve_method_name(
- (object ? object->ce : func->common.scope), func) :
- func->common.function_name;
+ function_name = func->common.function_name;
} else {
func = NULL;
function_name = NULL;
@@ -2520,9 +1990,8 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
}
zend_hash_add_new(Z_ARRVAL(stack_frame), ZSTR_KNOWN(ZEND_STR_CLASS), &tmp);
if ((options & DEBUG_BACKTRACE_PROVIDE_OBJECT) != 0) {
- ZVAL_OBJ(&tmp, object);
+ ZVAL_OBJ_COPY(&tmp, object);
zend_hash_add_new(Z_ARRVAL(stack_frame), ZSTR_KNOWN(ZEND_STR_OBJECT), &tmp);
- Z_ADDREF(tmp);
}
ZVAL_INTERNED_STR(&tmp, ZSTR_KNOWN(ZEND_STR_OBJECT_OPERATOR));
@@ -2544,13 +2013,12 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
/* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
zend_bool build_filename_arg = 1;
zend_string *pseudo_function_name;
+ uint32_t include_kind = 0;
+ if (ptr->func && ZEND_USER_CODE(ptr->func->common.type) && ptr->opline->opcode == ZEND_INCLUDE_OR_EVAL) {
+ include_kind = ptr->opline->extended_value;
+ }
- if (!ptr->func || !ZEND_USER_CODE(ptr->func->common.type) || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
- /* can happen when calling eval from a custom sapi */
- pseudo_function_name = ZSTR_KNOWN(ZEND_STR_UNKNOWN);
- build_filename_arg = 0;
- } else
- switch (ptr->opline->extended_value) {
+ switch (include_kind) {
case ZEND_EVAL:
pseudo_function_name = ZSTR_KNOWN(ZEND_STR_EVAL);
build_filename_arg = 0;
@@ -2568,8 +2036,12 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
pseudo_function_name = ZSTR_KNOWN(ZEND_STR_REQUIRE_ONCE);
break;
default:
- /* this can actually happen if you use debug_backtrace() in your error_handler and
- * you're in the top-scope */
+ /* Skip dummy frame unless it is needed to preserve filename/lineno info. */
+ if (!filename) {
+ zval_ptr_dtor(&stack_frame);
+ goto skip_frame;
+ }
+
pseudo_function_name = ZSTR_KNOWN(ZEND_STR_UNKNOWN);
build_filename_arg = 0;
break;
@@ -2595,38 +2067,36 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &stack_frame);
+skip_frame:
include_filename = filename;
-
call = skip;
ptr = skip->prev_execute_data;
}
}
/* }}} */
-/* {{{ proto array debug_backtrace([int options[, int limit]])
- Return backtrace as array */
+/* {{{ Return backtrace as array */
ZEND_FUNCTION(debug_backtrace)
{
zend_long options = DEBUG_BACKTRACE_PROVIDE_OBJECT;
zend_long limit = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|ll", &options, &limit) == FAILURE) {
- return;
+ RETURN_THROWS();
}
zend_fetch_debug_backtrace(return_value, 1, options, limit);
}
/* }}} */
-/* {{{ proto bool extension_loaded(string extension_name)
- Returns true if the named extension is loaded */
+/* {{{ Returns true if the named extension is loaded */
ZEND_FUNCTION(extension_loaded)
{
zend_string *extension_name;
zend_string *lcname;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
- return;
+ RETURN_THROWS();
}
lcname = zend_string_tolower(extension_name);
@@ -2639,18 +2109,17 @@ ZEND_FUNCTION(extension_loaded)
}
/* }}} */
-/* {{{ proto array get_extension_funcs(string extension_name)
- Returns an array with the names of functions belonging to the named extension */
+/* {{{ Returns an array with the names of functions belonging to the named extension */
ZEND_FUNCTION(get_extension_funcs)
{
zend_string *extension_name;
zend_string *lcname;
- int array;
+ bool array;
zend_module_entry *module;
zend_function *zif;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &extension_name) == FAILURE) {
- return;
+ RETURN_THROWS();
}
if (strncasecmp(ZSTR_VAL(extension_name), "zend", sizeof("zend"))) {
lcname = zend_string_tolower(extension_name);