summaryrefslogtreecommitdiff
path: root/ext/reflection
diff options
context:
space:
mode:
authorChristian Seiler <cseiler@php.net>2009-01-26 22:54:34 +0000
committerChristian Seiler <cseiler@php.net>2009-01-26 22:54:34 +0000
commitc6d89bd4a8650ac76e14a30353d334de99e7b997 (patch)
treee52e118c2ed6cc64a0251e125a8802956b574660 /ext/reflection
parent7cb513c19ad3beecc8b5b1d635899d4d89c0946c (diff)
downloadphp-git-c6d89bd4a8650ac76e14a30353d334de99e7b997.tar.gz
[DOC] Remove $this support in closures for PHP 5.3 beta 1
- Implementation notes here: http://wiki.php.net/rfc/closures/removal-of-this
Diffstat (limited to 'ext/reflection')
-rw-r--r--ext/reflection/php_reflection.c266
-rwxr-xr-xext/reflection/tests/027.phpt75
-rw-r--r--ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt37
-rw-r--r--ext/reflection/tests/ReflectionFunction_getClosure_error.phpt27
-rw-r--r--ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt55
-rw-r--r--ext/reflection/tests/ReflectionMethod_getClosure_error.phpt77
-rwxr-xr-xext/reflection/tests/closures_001.phpt2
-rwxr-xr-xext/reflection/tests/closures_002.phpt6
-rw-r--r--ext/reflection/tests/closures_003.phpt4
-rw-r--r--ext/reflection/tests/closures_004.phpt27
10 files changed, 98 insertions, 478 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 859b9a93ed..ee137231d2 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -326,7 +326,7 @@ static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_
}
static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
-static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, zval* prop_name, zval* closure, char *indent TSRMLS_DC);
+static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char *indent TSRMLS_DC);
static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
@@ -492,7 +492,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
&& ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
{
string_printf(str, "\n");
- _function_string(str, mptr, ce, NULL, NULL, sub_indent.string TSRMLS_CC);
+ _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
}
zend_hash_move_forward_ex(&ce->function_table, &pos);
}
@@ -594,7 +594,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
closure = NULL;
}
string_printf(&dyn, "\n");
- _function_string(&dyn, mptr, ce, NULL, NULL, sub_indent.string TSRMLS_CC);
+ _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
count++;
_free_function(closure TSRMLS_CC);
}
@@ -750,8 +750,42 @@ static void _function_parameter_string(string *str, zend_function *fptr, char* i
}
/* }}} */
+/* {{{ _function_closure_string */
+static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
+{
+ zend_uint i, count;
+ ulong num_index;
+ char *key;
+ uint key_len;
+ HashTable *static_variables;
+ HashPosition pos;
+
+ if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
+ return;
+ }
+
+ static_variables = fptr->op_array.static_variables;
+ count = zend_hash_num_elements(static_variables);
+
+ if (!count) {
+ return;
+ }
+
+ string_printf(str, "\n");
+ string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
+ zend_hash_internal_pointer_reset_ex(static_variables, &pos);
+ i = 0;
+ while (i < count) {
+ zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
+ string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, key);
+ zend_hash_move_forward_ex(static_variables, &pos);
+ }
+ string_printf(str, "%s}\n", indent);
+}
+/* }}} */
+
/* {{{ _function_string */
-static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, zval* prop_name, zval* closure, char* indent TSRMLS_DC)
+static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
{
string param_indent;
zend_function *overwrites;
@@ -767,7 +801,7 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
}
string_write(str, indent, strlen(indent));
- string_printf(str, closure ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
+ string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
string_printf(str, ", deprecated");
@@ -835,7 +869,7 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
if (fptr->op_array.return_reference) {
string_printf(str, "&");
}
- string_printf(str, "%s ] {\n", closure && prop_name ? Z_STRVAL_P(prop_name) : fptr->common.function_name);
+ string_printf(str, "%s ] {\n", fptr->common.function_name);
/* The information where a function is declared is only available for user classes */
if (fptr->type == ZEND_USER_FUNCTION) {
string_printf(str, "%s @@ %s %d - %d\n", indent,
@@ -843,38 +877,11 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
fptr->op_array.line_start,
fptr->op_array.line_end);
}
- if (closure) {
- const zend_function *closure_fptr = zend_get_closure_method_def(closure TSRMLS_CC);
- zval *closure_this = zend_get_closure_this_ptr(closure TSRMLS_CC);
- HashTable *static_variables = NULL;
- int index = 0, count = closure_this ? 1 : 0;
- if (closure_fptr->type == ZEND_USER_FUNCTION && closure_fptr->op_array.static_variables) {
- static_variables = closure_fptr->op_array.static_variables;
- count += zend_hash_num_elements(static_variables);
- }
- if (count) {
- string_printf(str, "\n");
- string_printf(str, "%s - Static Parameters [%d] {\n", indent, count);
- if (closure_this) {
- string_printf(str, "%s Parameter #%d [ %s $this ]\n", indent, index++, Z_OBJCE_P(closure_this)->name);
- }
- if (static_variables) {
- HashPosition pos;
- uint key_len;
- char* key;
- ulong num_index;
- zend_hash_internal_pointer_reset_ex(static_variables, &pos);
- while (index < count) {
- zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
- string_printf(str, "%s Parameter #%d [ $%s ]\n", indent, index++, key);
- zend_hash_move_forward_ex(static_variables, &pos);
- }
- }
- string_printf(str, "%s }\n", indent);
- }
- }
string_init(&param_indent);
string_printf(&param_indent, "%s ", indent);
+ if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
+ _function_closure_string(str, fptr, param_indent.string TSRMLS_CC);
+ }
_function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
string_free(&param_indent);
string_printf(str, "%s}\n", indent);
@@ -1075,7 +1082,7 @@ static void _extension_string(string *str, zend_module_entry *module, char *inde
continue;
}
- _function_string(str, fptr, NULL, NULL, NULL, " " TSRMLS_CC);
+ _function_string(str, fptr, NULL, " " TSRMLS_CC);
func++;
}
string_printf(str, "%s }\n", indent);
@@ -1164,12 +1171,15 @@ static void reflection_extension_factory(zval *object, const char *name_str TSRM
/* }}} */
/* {{{ reflection_parameter_factory */
-static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
+static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
{
reflection_object *intern;
parameter_reference *reference;
zval *name;
+ if (closure_object) {
+ Z_ADDREF_P(closure_object);
+ }
MAKE_STD_ZVAL(name);
if (arg_info->name) {
ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
@@ -1186,16 +1196,20 @@ static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_i
intern->ptr = reference;
intern->ref_type = REF_TYPE_PARAMETER;
intern->ce = fptr->common.scope;
+ intern->obj = closure_object;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
}
/* }}} */
/* {{{ reflection_function_factory */
-static void reflection_function_factory(zend_function *function, zval *object TSRMLS_DC)
+static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC)
{
reflection_object *intern;
zval *name;
+ if (closure_object) {
+ Z_ADDREF_P(closure_object);
+ }
MAKE_STD_ZVAL(name);
ZVAL_STRING(name, function->common.function_name, 1);
@@ -1204,17 +1218,21 @@ static void reflection_function_factory(zend_function *function, zval *object TS
intern->ptr = function;
intern->ref_type = REF_TYPE_FUNCTION;
intern->ce = NULL;
+ intern->obj = closure_object;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
}
/* }}} */
/* {{{ reflection_method_factory */
-static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *object TSRMLS_DC)
+static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC)
{
reflection_object *intern;
zval *name;
zval *classname;
+ if (closure_object) {
+ Z_ADDREF_P(closure_object);
+ }
MAKE_STD_ZVAL(name);
MAKE_STD_ZVAL(classname);
ZVAL_STRING(name, method->common.function_name, 1);
@@ -1224,6 +1242,7 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
intern->ptr = method;
intern->ref_type = REF_TYPE_FUNCTION;
intern->ce = ce;
+ intern->obj = closure_object;
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
}
@@ -1522,15 +1541,13 @@ ZEND_METHOD(reflection_function, __toString)
reflection_object *intern;
zend_function *fptr;
string str;
- zval* name;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
GET_REFLECTION_OBJECT_PTR(fptr);
- _default_lookup_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
string_init(&str);
- _function_string(&str, fptr, intern->ce, name, intern->obj, "" TSRMLS_CC);
+ _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
RETURN_STRINGL(str.string, str.len - 1, 0);
}
/* }}} */
@@ -1557,28 +1574,7 @@ ZEND_METHOD(reflection_function, isClosure)
return;
}
GET_REFLECTION_OBJECT_PTR(fptr);
- RETURN_BOOL(intern->obj);
-}
-/* }}} */
-
-/* {{{ proto public bool ReflectionFunction::getClosureThis()
- Returns this pointer bound to closure */
-ZEND_METHOD(reflection_function, getClosureThis)
-{
- reflection_object *intern;
- zend_function *fptr;
- zval* closure_this;
-
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
- GET_REFLECTION_OBJECT_PTR(fptr);
- if (intern->obj) {
- closure_this = zend_get_closure_this_ptr(intern->obj TSRMLS_CC);
- if (closure_this) {
- RETURN_ZVAL(closure_this, 1, 0);
- }
- }
+ RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
}
/* }}} */
@@ -1719,22 +1715,6 @@ ZEND_METHOD(reflection_function, getStaticVariables)
}
/* }}} */
-/* {{{ proto public mixed ReflectionFunction::getClosure()
- Returns a dynamically created closure for the function */
-ZEND_METHOD(reflection_function, getClosure)
-{
- reflection_object *intern;
- zend_function *fptr;
-
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
- GET_REFLECTION_OBJECT_PTR(fptr);
-
- zend_create_closure(return_value, fptr, NULL, NULL TSRMLS_CC);
-}
-/* }}} */
-
/* {{{ proto public mixed ReflectionFunction::invoke(mixed* args)
Invokes the function */
ZEND_METHOD(reflection_function, invoke)
@@ -1912,7 +1892,7 @@ ZEND_METHOD(reflection_function, getParameters)
zval *parameter;
ALLOC_ZVAL(parameter);
- reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
+ reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), intern->obj, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
add_next_index_zval(return_value, parameter);
arg_info++;
@@ -1989,6 +1969,7 @@ ZEND_METHOD(reflection_parameter, __construct)
struct _zend_arg_info *arg_info;
int position;
zend_class_entry *ce = NULL;
+ zend_bool is_closure = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, &parameter) == FAILURE) {
return;
@@ -2053,7 +2034,8 @@ ZEND_METHOD(reflection_parameter, __construct)
&& memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
&& (fptr = zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL)
{
- /* nothign to do */
+ /* nothign to do. don't set is_closure since is the invoke handler,
+ not the closure itself */
} else if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
efree(lcname);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
@@ -2068,7 +2050,9 @@ ZEND_METHOD(reflection_parameter, __construct)
ce = Z_OBJCE_P(reference);
if (instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
- fptr = zend_get_closure_invoke_method(reference TSRMLS_CC);
+ fptr = (zend_function *)zend_get_closure_method_def(reference TSRMLS_CC);
+ Z_ADDREF_P(reference);
+ is_closure = 1;
} else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == FAILURE) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
"Method %s::%s() does not exist", ce->name, ZEND_INVOKE_FUNC_NAME);
@@ -2132,10 +2116,13 @@ ZEND_METHOD(reflection_parameter, __construct)
ref->offset = (zend_uint)position;
ref->required = fptr->common.required_num_args;
ref->fptr = fptr;
- // TODO: copy fptr
+ /* TODO: copy fptr */
intern->ptr = ref;
intern->ref_type = REF_TYPE_PARAMETER;
intern->ce = ce;
+ if (reference && is_closure) {
+ intern->obj = reference;
+ }
}
/* }}} */
@@ -2181,9 +2168,9 @@ ZEND_METHOD(reflection_parameter, getDeclaringFunction)
GET_REFLECTION_OBJECT_PTR(param);
if (!param->fptr->common.scope) {
- reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
+ reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
} else {
- reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
+ reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
}
}
/* }}} */
@@ -2431,11 +2418,7 @@ ZEND_METHOD(reflection_method, __construct)
int name_len, tmp_len;
zval ztmp;
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "o", &classname) == SUCCESS) {
- name_str = ZEND_INVOKE_FUNC_NAME;
- name_len = sizeof(ZEND_INVOKE_FUNC_NAME)-1;
- orig_obj = classname;
- } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
return;
}
@@ -2504,45 +2487,15 @@ ZEND_METHOD(reflection_method, __construct)
{
/* do nothing, mptr already set */
} else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
- /* Check if this is a property storing a closure */
- mptr = NULL; /* Set by closure detection again */
- if (orig_obj) {
- zval **callable, member;
- zend_property_info *property_info;
- zend_object *zobj = zend_objects_get_address(orig_obj TSRMLS_CC);
-
- ZVAL_STRINGL(&member, name_str, name_len, 0);
- property_info = zend_get_property_info(ce, &member, 1 TSRMLS_CC);
-
- if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &callable) == SUCCESS) {
- zval *callable_obj;
- zend_class_entry *ce_ptr;
- zend_function *fbc;
-
- if (Z_TYPE_PP(callable) == IS_OBJECT
- && Z_OBJ_HANDLER_PP(callable, get_closure)
- && Z_OBJ_HANDLER_PP(callable, get_closure)(*callable, &ce_ptr, &fbc, &callable_obj TSRMLS_CC) == SUCCESS) {
- mptr = fbc;
- Z_ADDREF_PP(callable);
- intern->obj = *callable;
- }
- }
- }
- if (!mptr) {
- efree(lcname);
- zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Method %s::%s() does not exist", ce->name, name_str);
- return;
- }
+ efree(lcname);
+ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
+ "Method %s::%s() does not exist", ce->name, name_str);
+ return;
}
efree(lcname);
MAKE_STD_ZVAL(name);
- if (intern->obj) {
- ZVAL_STRINGL(name, name_str, name_len, 1);
- } else {
- ZVAL_STRING(name, mptr->common.function_name, 1);
- }
+ ZVAL_STRING(name, mptr->common.function_name, 1);
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
intern->ptr = mptr;
intern->ref_type = REF_TYPE_FUNCTION;
@@ -2557,54 +2510,17 @@ ZEND_METHOD(reflection_method, __toString)
reflection_object *intern;
zend_function *mptr;
string str;
- zval *name;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
GET_REFLECTION_OBJECT_PTR(mptr);
- _default_lookup_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
string_init(&str);
- _function_string(&str, mptr, intern->ce, name, intern->obj, "" TSRMLS_CC);
+ _function_string(&str, mptr, intern->ce, "" TSRMLS_CC);
RETURN_STRINGL(str.string, str.len - 1, 0);
}
/* }}} */
-/* {{{ proto public mixed ReflectionMethod::getClosure([mixed object])
- Invokes the function */
-ZEND_METHOD(reflection_method, getClosure)
-{
- reflection_object *intern;
- zval *obj;
- zend_function *mptr;
-
- METHOD_NOTSTATIC(reflection_method_ptr);
- GET_REFLECTION_OBJECT_PTR(mptr);
-
- if (mptr->common.fn_flags & ZEND_ACC_STATIC) {
- zend_create_closure(return_value, mptr, mptr->common.scope, NULL TSRMLS_CC);
- } else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
- return;
- }
-
- if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope TSRMLS_CC)) {
- _DO_THROW("Given object is not an instance of the class this method was declared in");
- /* Returns from this function */
- }
-
- /* 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);
- }
- }
-}
-/* }}} */
-
/* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
Invokes the method. */
ZEND_METHOD(reflection_method, invoke)
@@ -3017,7 +2933,7 @@ ZEND_METHOD(reflection_method, getPrototype)
return;
}
- reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, return_value TSRMLS_CC);
+ reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value TSRMLS_CC);
}
/* }}} */
@@ -3397,7 +3313,7 @@ ZEND_METHOD(reflection_class, getConstructor)
GET_REFLECTION_OBJECT_PTR(ce);
if (ce->constructor) {
- reflection_method_factory(ce, ce->constructor, return_value TSRMLS_CC);
+ reflection_method_factory(ce, ce->constructor, NULL, return_value TSRMLS_CC);
} else {
RETURN_NULL();
}
@@ -3451,10 +3367,12 @@ ZEND_METHOD(reflection_class, getMethod)
&& memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
&& (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) != NULL)
{
- reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
+ /* don't assign closure_object since we only reflect the invoke handler
+ method and not the closure definition itself */
+ reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
efree(lc_name);
} else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
- reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
+ reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
efree(lc_name);
} else {
efree(lc_name);
@@ -3480,7 +3398,10 @@ static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval,
{
mptr = closure;
}
- reflection_method_factory(ce, mptr, method TSRMLS_CC);
+ /* don't assign closure_object since we only reflect the invoke handler
+ method and not the closure definition itself, even if we have a
+ closure */
+ reflection_method_factory(ce, mptr, NULL, method TSRMLS_CC);
add_next_index_zval(retval, method);
}
}
@@ -4839,7 +4760,7 @@ ZEND_METHOD(reflection_extension, getFunctions)
}
ALLOC_ZVAL(function);
- reflection_function_factory(fptr, function TSRMLS_CC);
+ reflection_function_factory(fptr, NULL, function TSRMLS_CC);
add_assoc_zval_ex(return_value, func->fname, strlen(func->fname)+1, function);
func++;
}
@@ -5090,7 +5011,6 @@ static const zend_function_entry reflection_function_abstract_functions[] = {
ZEND_ME(reflection_function, isDeprecated, NULL, 0)
ZEND_ME(reflection_function, isInternal, NULL, 0)
ZEND_ME(reflection_function, isUserDefined, NULL, 0)
- ZEND_ME(reflection_function, getClosureThis, NULL, 0)
ZEND_ME(reflection_function, getDocComment, NULL, 0)
ZEND_ME(reflection_function, getEndLine, NULL, 0)
ZEND_ME(reflection_function, getExtension, NULL, 0)
@@ -5113,7 +5033,6 @@ static const zend_function_entry reflection_function_functions[] = {
ZEND_ME(reflection_function, __toString, NULL, 0)
ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
ZEND_ME(reflection_function, isDisabled, NULL, 0)
- ZEND_ME(reflection_function, getClosure, NULL, 0)
ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
{NULL, NULL, NULL}
@@ -5153,7 +5072,6 @@ static const zend_function_entry reflection_method_functions[] = {
ZEND_ME(reflection_method, isConstructor, NULL, 0)
ZEND_ME(reflection_method, isDestructor, NULL, 0)
ZEND_ME(reflection_method, getModifiers, NULL, 0)
- ZEND_ME(reflection_method, getClosure, NULL, 0)
ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
ZEND_ME(reflection_method, getDeclaringClass, NULL, 0)
diff --git a/ext/reflection/tests/027.phpt b/ext/reflection/tests/027.phpt
deleted file mode 100755
index a2bda4feaa..0000000000
--- a/ext/reflection/tests/027.phpt
+++ /dev/null
@@ -1,75 +0,0 @@
---TEST--
---FILE--
-<?php
-
-$global = 42;
-
-$func = function($x, stdClass $y=NULL) use($global) {
- static $static;
-};
-
-ReflectionFunction::Export($func);
-
-$r = new ReflectionFunction($func);
-
-var_dump(@get_class($r->getClosureThis()));
-var_dump($r->getName());
-var_dump($r->isClosure());
-
-Class Test {
- public $func;
- function __construct(){
- global $global;
- $this->func = function($x, stdClass $y = NULL) use($global) {
- static $static;
- };
- }
-}
-
-ReflectionMethod::export(new Test, "func");
-
-$r = new ReflectionMethod(new Test, "func");
-
-var_dump(get_class($r->getClosureThis()));
-var_dump($r->getName());
-var_dump($r->isClosure());
-
-?>
-===DONE===
---EXPECTF--
-Closure [ <user> function {closure} ] {
- @@ %s027.php 5 - 7
-
- - Static Parameters [2] {
- Parameter #0 [ $global ]
- Parameter #1 [ $static ]
- }
-
- - Parameters [2] {
- Parameter #0 [ <required> $x ]
- Parameter #1 [ <optional> stdClass or NULL $y = NULL ]
- }
-}
-
-NULL
-string(9) "{closure}"
-bool(true)
-Closure [ <user> public method func ] {
- @@ %s027.php 21 - 23
-
- - Static Parameters [3] {
- Parameter #0 [ Test $this ]
- Parameter #1 [ $global ]
- Parameter #2 [ $static ]
- }
-
- - Parameters [2] {
- Parameter #0 [ <required> $x ]
- Parameter #1 [ <optional> stdClass or NULL $y = NULL ]
- }
-}
-
-string(4) "Test"
-string(4) "func"
-bool(true)
-===DONE===
diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt
deleted file mode 100644
index 832d31c5f5..0000000000
--- a/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt
+++ /dev/null
@@ -1,37 +0,0 @@
---TEST--
-Test ReflectionFunction::getClosure() function : basic functionality
---FILE--
-<?php
-/* Prototype : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the function
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions:
- */
-
-echo "*** Testing ReflectionFunction::getClosure() : basic functionality ***\n";
-
-function foo()
-{
- var_dump( "Inside foo function" );
-}
-
-function bar( $arg )
-{
- var_dump( "Arg is " . $arg );
-}
-
-$func = new ReflectionFunction( 'foo' );
-$closure = $func->getClosure();
-$closure();
-
-$func = new ReflectionFunction( 'bar' );
-$closure = $func->getClosure();
-$closure( 'succeeded' );
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionFunction::getClosure() : basic functionality ***
-%unicode|string%(19) "Inside foo function"
-%unicode|string%(16) "Arg is succeeded"
-===DONE===
diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt
deleted file mode 100644
index 9a963e41ca..0000000000
--- a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt
+++ /dev/null
@@ -1,27 +0,0 @@
---TEST--
-Test ReflectionFunction::getClosure() function : error functionality
---FILE--
-<?php
-/* Prototype : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the function
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions:
- */
-
-echo "*** Testing ReflectionFunction::getClosure() : error conditions ***\n";
-
-function foo()
-{
- var_dump( "Inside foo function" );
-}
-
-$func = new ReflectionFunction( 'foo' );
-$closure = $func->getClosure('bar');
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionFunction::getClosure() : error conditions ***
-
-Warning: ReflectionFunction::getClosure() expects exactly 0 parameters, 1 given in %s on line %d
-===DONE===
diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt
deleted file mode 100644
index d8bdbe110c..0000000000
--- a/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt
+++ /dev/null
@@ -1,55 +0,0 @@
---TEST--
-Test ReflectionMethod::getClosure() function : basic functionality
---FILE--
-<?php
-/* Prototype : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the method
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions:
- */
-
-echo "*** Testing ReflectionMethod::getClosure() : basic functionality ***\n";
-
-class StaticExample
-{
- static function foo()
- {
- var_dump( "Static Example class, Hello World!" );
- }
-}
-
-class Example
-{
- public $bar = 42;
- public function foo()
- {
- var_dump( "Example class, bar: " . $this->bar );
- }
-}
-
-// Initialize classes
-$class = new ReflectionClass( 'Example' );
-$staticclass = new ReflectionClass( 'StaticExample' );
-$object = new Example();
-$fakeobj = new StdClass();
-
-
-$method = $staticclass->getMethod( 'foo' );
-$closure = $method->getClosure();
-$closure();
-
-$method = $class->getMethod( 'foo' );
-
-$closure = $method->getClosure( $object );
-$closure();
-$object->bar = 34;
-$closure();
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionMethod::getClosure() : basic functionality ***
-%unicode|string%(34) "Static Example class, Hello World!"
-%unicode|string%(22) "Example class, bar: 42"
-%unicode|string%(22) "Example class, bar: 34"
-===DONE===
diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt
deleted file mode 100644
index 6f1e91ea2f..0000000000
--- a/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt
+++ /dev/null
@@ -1,77 +0,0 @@
---TEST--
-Test ReflectionMethod::getClosure() function : error functionality
---FILE--
-<?php
-/* Prototype : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the method
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions:
- */
-
-echo "*** Testing ReflectionMethod::getClosure() : error conditions ***\n";
-
-class StaticExample
-{
- static function foo()
- {
- var_dump( "Static Example class, Hello World!" );
- }
-}
-
-class Example
-{
- public $bar = 42;
- public function foo()
- {
- var_dump( "Example class, bar: " . $this->bar );
- }
-}
-
-// Initialize classes
-$class = new ReflectionClass( 'Example' );
-$staticclass = new ReflectionClass( 'StaticExample' );
-$method = $class->getMethod( 'foo' );
-$staticmethod = $staticclass->getMethod( 'foo' );
-$object = new Example();
-$fakeobj = new StdClass();
-
-echo "\n-- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --\n";
-var_dump( $staticmethod->getClosure( 'foobar' ) );
-var_dump( $staticmethod->getClosure( 'foo', 'bar' ) );
-var_dump( $method->getClosure( $object, 'foobar' ) );
-
-echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n";
-$closure = $method->getClosure();
-
-echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n";
-try {
- var_dump( $method->getClosure( $fakeobj ) );
-} catch( Exception $e ) {
- var_dump( $e->getMessage() );
-}
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionMethod::getClosure() : error conditions ***
-
--- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --
-object(Closure)#%d (1) {
- ["this"]=>
- NULL
-}
-object(Closure)#%d (1) {
- ["this"]=>
- NULL
-}
-
-Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 2 given in %s on line %d
-NULL
-
--- Testing ReflectionMethod::getClosure() function with Zero arguments --
-
-Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 0 given in %s on line %d
-
--- Testing ReflectionMethod::getClosure() function with Zero arguments --
-%unicode|string%(72) "Given object is not an instance of the class this method was declared in"
-===DONE===
diff --git a/ext/reflection/tests/closures_001.phpt b/ext/reflection/tests/closures_001.phpt
index cd8815c2b7..6cc7e6755c 100755
--- a/ext/reflection/tests/closures_001.phpt
+++ b/ext/reflection/tests/closures_001.phpt
@@ -19,7 +19,7 @@ foreach($rms as $rm) {
echo "---\n";
-$rm = new ReflectionMethod($closure);
+$rm = new ReflectionMethod($closure, '__invoke');
var_dump($rm->getName());
var_dump($rm->getNumberOfParameters());
var_dump($rm->getNumberOfRequiredParameters());
diff --git a/ext/reflection/tests/closures_002.phpt b/ext/reflection/tests/closures_002.phpt
index d6660de74b..e8b080f5cb 100755
--- a/ext/reflection/tests/closures_002.phpt
+++ b/ext/reflection/tests/closures_002.phpt
@@ -7,15 +7,15 @@ class Test {
function __invoke($a, $b = 0) { }
}
-$rm = new ReflectionMethod(new Test);
+$rm = new ReflectionMethod(new Test, '__invoke');
var_dump($rm->getName());
var_dump($rm->getNumberOfParameters());
var_dump($rm->getNumberOfRequiredParameters());
-$rp = new ReflectionParameter(new Test, 0);
+$rp = new ReflectionParameter(array(new Test, '__invoke'), 0);
var_dump($rp->isOptional());
-$rp = new ReflectionParameter(new Test, 1);
+$rp = new ReflectionParameter(array(new Test, '__invoke'), 1);
var_dump($rp->isOptional());
?>
diff --git a/ext/reflection/tests/closures_003.phpt b/ext/reflection/tests/closures_003.phpt
index cc309397b5..4483dc06e3 100644
--- a/ext/reflection/tests/closures_003.phpt
+++ b/ext/reflection/tests/closures_003.phpt
@@ -5,14 +5,14 @@ Reflection on closures: Segfaults with getParameters() and getDeclaringFunction(
$closure = function($a, $b = 0) { };
-$method = new ReflectionMethod ($closure);
+$method = new ReflectionMethod ($closure, '__invoke');
$params = $method->getParameters ();
unset ($method);
$method = $params[0]->getDeclaringFunction ();
unset ($params);
echo $method->getName ()."\n";
-$parameter = new ReflectionParameter ($closure, 'b');
+$parameter = new ReflectionParameter (array ($closure, '__invoke'), 'b');
$method = $parameter->getDeclaringFunction ();
unset ($parameter);
echo $method->getName ()."\n";
diff --git a/ext/reflection/tests/closures_004.phpt b/ext/reflection/tests/closures_004.phpt
deleted file mode 100644
index 6b75045910..0000000000
--- a/ext/reflection/tests/closures_004.phpt
+++ /dev/null
@@ -1,27 +0,0 @@
---TEST--
-Reflection on closures: Segfault with getClosure() on closure itself
---FILE--
-<?php
-
-$closure = function() { echo "Invoked!\n"; };
-
-$method = new ReflectionMethod ($closure);
-
-$closure2 = $method->getClosure ($closure);
-
-$closure2 ();
-$closure2->__invoke ();
-
-unset ($closure);
-
-$closure2 ();
-$closure2->__invoke ();
-
-?>
-===DONE===
---EXPECTF--
-Invoked!
-Invoked!
-Invoked!
-Invoked!
-===DONE===