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.c125
1 files changed, 99 insertions, 26 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index a576455fa3..e5f77d8960 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -31,6 +31,12 @@
#undef ZEND_TEST_EXCEPTIONS
+#if ZEND_DEBUG
+static zend_class_entry *zend_test_interface;
+static zend_class_entry *zend_test_class;
+static zend_object_handlers zend_test_class_handlers;
+#endif
+
static ZEND_FUNCTION(zend_version);
static ZEND_FUNCTION(func_num_args);
static ZEND_FUNCTION(func_get_arg);
@@ -257,6 +263,51 @@ ZEND_END_ARG_INFO()
/* }}} */
+#if ZEND_DEBUG
+static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ {
+ zend_object *obj = zend_objects_new(class_type);
+ obj->handlers = &zend_test_class_handlers;
+ return obj;
+}
+/* }}} */
+
+static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ {
+ zend_internal_function *fptr = emalloc(sizeof(zend_internal_function));
+ fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY;
+ fptr->num_args = 1;
+ fptr->arg_info = NULL;
+ fptr->scope = (*object)->ce;
+ fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
+ fptr->function_name = zend_string_copy(name);
+ fptr->handler = ZEND_FN(zend_test_func);
+ zend_set_function_arg_flags((zend_function*)fptr);
+
+ return (zend_function*)fptr;
+}
+/* }}} */
+
+static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ {
+ zend_internal_function *fptr = emalloc(sizeof(zend_internal_function));
+ fptr->type = ZEND_OVERLOADED_FUNCTION;
+ fptr->num_args = 1;
+ fptr->arg_info = NULL;
+ fptr->scope = ce;
+ fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC;
+ fptr->function_name = name;
+ fptr->handler = ZEND_FN(zend_test_func);
+ zend_set_function_arg_flags((zend_function*)fptr);
+
+ return (zend_function*)fptr;
+}
+/* }}} */
+
+static int zend_test_class_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ {
+ RETVAL_STR(zend_string_copy(method));
+ return 0;
+}
+/* }}} */
+#endif
+
static const zend_function_entry builtin_functions[] = { /* {{{ */
ZEND_FE(zend_version, arginfo_zend__void)
ZEND_FE(func_num_args, arginfo_zend__void)
@@ -339,6 +390,21 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */
zend_register_default_classes();
+#if ZEND_DEBUG
+ INIT_CLASS_ENTRY(class_entry, "_ZendTestInterface", NULL);
+ zend_test_interface = zend_register_internal_interface(&class_entry);
+ zend_declare_class_constant_long(zend_test_interface, ZEND_STRL("DUMMY"), 0);
+ INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", NULL);
+ zend_test_class = zend_register_internal_class_ex(&class_entry, NULL);
+ zend_class_implements(zend_test_class, 1, zend_test_interface);
+ zend_test_class->create_object = zend_test_class_new;
+ zend_test_class->get_static_method = zend_test_class_static_method_get;
+
+ memcpy(&zend_test_class_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zend_test_class_handlers.get_method = zend_test_class_method_get;
+ zend_test_class_handlers.call_method = zend_test_class_call_method;
+#endif
+
return SUCCESS;
}
/* }}} */
@@ -460,13 +526,13 @@ ZEND_FUNCTION(func_get_arg)
arg_count = ZEND_CALL_NUM_ARGS(ex);
- if (requested_offset >= arg_count) {
+ 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;
}
first_extra_arg = ex->func->op_array.num_args;
- if (requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) {
+ if ((zend_ulong)requested_offset >= first_extra_arg && (ZEND_CALL_NUM_ARGS(ex) > first_extra_arg)) {
arg = ZEND_CALL_VAR_NUM(ex, ex->func->op_array.last_var + ex->func->op_array.T) + (requested_offset - first_extra_arg);
} else {
arg = ZEND_CALL_ARG(ex, requested_offset + 1);
@@ -689,7 +755,7 @@ ZEND_FUNCTION(each)
Return the current error_reporting level, and if an argument was passed - change to the new level */
ZEND_FUNCTION(error_reporting)
{
- zval *err;
+ zval *err = NULL;
int old_error_reporting;
#ifndef FAST_ZPP
@@ -916,7 +982,7 @@ ZEND_FUNCTION(defined)
ZEND_PARSE_PARAMETERS_END();
#endif
- if (zend_get_constant_ex(name, NULL, ZEND_FETCH_CLASS_SILENT)) {
+ if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) {
RETURN_TRUE;
} else {
RETURN_FALSE;
@@ -935,8 +1001,10 @@ ZEND_FUNCTION(get_class)
}
if (!obj) {
- if (EG(scope)) {
- RETURN_STR_COPY(EG(scope)->name);
+ zend_class_entry *scope = zend_get_executed_scope();
+
+ if (scope) {
+ RETURN_STR_COPY(scope->name);
} else {
zend_error(E_WARNING, "get_class() called without object from outside a class");
RETURN_FALSE;
@@ -960,8 +1028,11 @@ ZEND_FUNCTION(get_called_class)
called_scope = zend_get_called_scope(execute_data);
if (called_scope) {
RETURN_STR_COPY(called_scope->name);
- } else if (!EG(scope)) {
- zend_error(E_WARNING, "get_called_class() called from outside a class");
+ } else {
+ zend_class_entry *scope = zend_get_executed_scope();
+ if (!scope) {
+ zend_error(E_WARNING, "get_called_class() called from outside a class");
+ }
}
RETURN_FALSE;
}
@@ -979,7 +1050,7 @@ ZEND_FUNCTION(get_parent_class)
}
if (!ZEND_NUM_ARGS()) {
- ce = EG(scope);
+ ce = zend_get_executed_scope();
if (ce && ce->parent) {
RETURN_STR_COPY(ce->parent->name);
} else {
@@ -1076,7 +1147,7 @@ ZEND_FUNCTION(is_a)
/* }}} */
/* {{{ add_class_vars */
-static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value)
+static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int statics, zval *return_value)
{
zend_property_info *prop_info;
zval *prop, prop_copy;
@@ -1084,12 +1155,12 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
if (((prop_info->flags & ZEND_ACC_SHADOW) &&
- prop_info->ce != EG(scope)) ||
+ prop_info->ce != scope) ||
((prop_info->flags & ZEND_ACC_PROTECTED) &&
- !zend_check_protected(prop_info->ce, EG(scope))) ||
+ !zend_check_protected(prop_info->ce, scope)) ||
((prop_info->flags & ZEND_ACC_PRIVATE) &&
- ce != EG(scope) &&
- prop_info->ce != EG(scope))) {
+ ce != scope &&
+ prop_info->ce != scope)) {
continue;
}
prop = NULL;
@@ -1114,7 +1185,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
/* this is necessary to make it able to work with default array
* properties, returned to user */
if (Z_OPT_CONSTANT_P(prop)) {
- if (UNEXPECTED(zval_update_constant_ex(prop, 0, NULL) != SUCCESS)) {
+ if (UNEXPECTED(zval_update_constant_ex(prop, NULL) != SUCCESS)) {
return;
}
}
@@ -1129,7 +1200,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
ZEND_FUNCTION(get_class_vars)
{
zend_string *class_name;
- zend_class_entry *ce;
+ zend_class_entry *ce, *scope;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &class_name) == FAILURE) {
return;
@@ -1145,8 +1216,9 @@ ZEND_FUNCTION(get_class_vars)
return;
}
}
- add_class_vars(ce, 0, return_value);
- add_class_vars(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);
}
}
/* }}} */
@@ -1244,6 +1316,7 @@ 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;
@@ -1262,15 +1335,16 @@ ZEND_FUNCTION(get_class_methods)
}
array_init(return_value);
+ scope = zend_get_executed_scope();
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) {
if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC)
- || (EG(scope) &&
+ || (scope &&
(((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
- zend_check_protected(mptr->common.scope, EG(scope)))
+ zend_check_protected(mptr->common.scope, scope))
|| ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
- EG(scope) == mptr->common.scope)))) {
+ scope == mptr->common.scope)))) {
size_t len = ZSTR_LEN(mptr->common.function_name);
/* Do not display old-style inherited constructors */
@@ -2036,17 +2110,16 @@ ZEND_FUNCTION(zend_test_func)
{
zval *arg1, *arg2;
- zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2);
+ zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2);
}
ZEND_FUNCTION(zend_test_func2)
{
zval *arg1, *arg2;
- zend_get_parameters(ZEND_NUM_ARGS(), 2, &arg1, &arg2);
+ zend_parse_parameters(ZEND_NUM_ARGS(), "|zz", &arg1, &arg2);
}
-
#ifdef ZTS
ZEND_FUNCTION(zend_thread_id)
{
@@ -2368,7 +2441,7 @@ ZEND_FUNCTION(debug_print_backtrace)
}
/* $this may be passed into regular internal functions */
- object = Z_OBJ(call->This);
+ object = (Z_TYPE(call->This) == IS_OBJECT) ? Z_OBJ(call->This) : NULL;
if (call->func) {
func = call->func;
@@ -2587,7 +2660,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
}
/* $this may be passed into regular internal functions */
- object = call ? Z_OBJ(call->This) : NULL;
+ object = (call && (Z_TYPE(call->This) == IS_OBJECT)) ? Z_OBJ(call->This) : NULL;
if (call && call->func) {
func = call->func;