summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/reflection/php_reflection.c')
-rw-r--r--ext/reflection/php_reflection.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index ba8de28b7e..a096ac4acd 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -231,6 +231,24 @@ static void reflection_register_implement(zend_class_entry *class_entry, zend_cl
class_entry->interfaces[num_interfaces - 1] = interface_entry;
}
+static zend_function *_copy_function(zend_function *fptr TSRMLS_DC) /* {{{ */
+{
+ if (fptr
+ && fptr->type == ZEND_INTERNAL_FUNCTION
+ && (fptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
+ {
+ zend_function *copy_fptr;
+ copy_fptr = emalloc(sizeof(zend_function));
+ memcpy(copy_fptr, fptr, sizeof(zend_function));
+ copy_fptr->internal_function.function_name = estrdup(fptr->internal_function.function_name);
+ return copy_fptr;
+ } else {
+ /* no copy needed */
+ return fptr;
+ }
+}
+/* }}} */
+
static void _free_function(zend_function *fptr TSRMLS_DC) /* {{{ */
{
if (fptr
@@ -1782,7 +1800,7 @@ ZEND_METHOD(reflection_function, getParameters)
zval *parameter;
ALLOC_ZVAL(parameter);
- reflection_parameter_factory(fptr, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
+ reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
add_next_index_zval(return_value, parameter);
arg_info++;
@@ -2033,9 +2051,9 @@ ZEND_METHOD(reflection_parameter, getDeclaringFunction)
GET_REFLECTION_OBJECT_PTR(param);
if (!param->fptr->common.scope) {
- reflection_function_factory(param->fptr, return_value TSRMLS_CC);
+ reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
} else {
- reflection_method_factory(param->fptr->common.scope, param->fptr, return_value TSRMLS_CC);
+ reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
}
}
/* }}} */
@@ -2393,7 +2411,14 @@ ZEND_METHOD(reflection_method, getClosure)
/* Returns from this function */
}
- zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC);
+ /* This is an original closure object and __invoke is to be called. */
+ if (Z_OBJCE_P(obj) == zend_ce_closure && mptr->type == ZEND_INTERNAL_FUNCTION &&
+ (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
+ {
+ RETURN_ZVAL(obj, 1, 0);
+ } else {
+ zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC);
+ }
}
}
/* }}} */