diff options
author | Christian Seiler <cseiler@php.net> | 2009-01-26 22:54:34 +0000 |
---|---|---|
committer | Christian Seiler <cseiler@php.net> | 2009-01-26 22:54:34 +0000 |
commit | c6d89bd4a8650ac76e14a30353d334de99e7b997 (patch) | |
tree | e52e118c2ed6cc64a0251e125a8802956b574660 | |
parent | 7cb513c19ad3beecc8b5b1d635899d4d89c0946c (diff) | |
download | php-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
22 files changed, 113 insertions, 693 deletions
diff --git a/Zend/tests/closure_005.phpt b/Zend/tests/closure_005.phpt deleted file mode 100644 index 4e32faa017..0000000000 --- a/Zend/tests/closure_005.phpt +++ /dev/null @@ -1,74 +0,0 @@ ---TEST-- -Closure 005: Lambda inside class, lifetime of $this ---FILE-- -<?php - -class A { - private $x; - - function __construct($x) { - $this->x = $x; - } - - function __destruct() { - echo "Destroyed\n"; - } - - function getIncer($val) { - return function() use ($val) { - $this->x += $val; - }; - } - - function getPrinter() { - return function() { - echo $this->x."\n"; - }; - } - - function getError() { - return static function() { - echo $this->x."\n"; - }; - } - - function printX() { - echo $this->x."\n"; - } -} - -$a = new A(3); -$incer = $a->getIncer(2); -$printer = $a->getPrinter(); -$error = $a->getError(); - -$a->printX(); -$printer(); -$incer(); -$a->printX(); -$printer(); - -unset($a); - -$incer(); -$printer(); - -unset($incer); -$printer(); - -unset($printer); - -$error(); - -echo "Done\n"; -?> ---EXPECTF-- -3 -3 -5 -5 -7 -7 -Destroyed - -Fatal error: Using $this when not in object context in %sclosure_005.php on line 28 diff --git a/Zend/tests/closure_007.phpt b/Zend/tests/closure_007.phpt deleted file mode 100644 index 89cd06d8a1..0000000000 --- a/Zend/tests/closure_007.phpt +++ /dev/null @@ -1,38 +0,0 @@ ---TEST-- -Closure 007: Nested lambdas in classes ---FILE-- -<?php - -class A { - private $x = 0; - - function getClosureGetter () { - return function () { - return function () { - $this->x++; - }; - }; - } - - function printX () { - echo $this->x."\n"; - } -} - -$a = new A; -$a->printX(); -$getClosure = $a->getClosureGetter(); -$a->printX(); -$closure = $getClosure(); -$a->printX(); -$closure(); -$a->printX(); - -echo "Done\n"; -?> ---EXPECT-- -0 -0 -0 -1 -Done diff --git a/Zend/tests/closure_020.phpt b/Zend/tests/closure_020.phpt index e34360d63e..7b4c60b9bd 100644 --- a/Zend/tests/closure_020.phpt +++ b/Zend/tests/closure_020.phpt @@ -27,22 +27,7 @@ object(foo)#%d (%d) { ["test":"foo":private]=> int(3) ["a"]=> - object(Closure)#%d (2) { - ["this"]=> - object(foo)#%d (2) { - ["test":"foo":private]=> - int(3) - ["a"]=> - object(Closure)#%d (2) { - ["this"]=> - *RECURSION* - ["static"]=> - array(1) { - ["a"]=> - *RECURSION* - } - } - } + object(Closure)#%d (1) { ["static"]=> array(1) { ["a"]=> @@ -50,9 +35,7 @@ object(foo)#%d (%d) { ["test":"foo":private]=> int(3) ["a"]=> - object(Closure)#%d (2) { - ["this"]=> - *RECURSION* + object(Closure)#%d (1) { ["static"]=> array(1) { ["a"]=> diff --git a/Zend/tests/closure_026.phpt b/Zend/tests/closure_026.phpt index 87829a33a2..f9e6bd5e25 100644 --- a/Zend/tests/closure_026.phpt +++ b/Zend/tests/closure_026.phpt @@ -32,18 +32,7 @@ object(foo)#%d (1) { ["a"]=> array(1) { [0]=> - object(Closure)#%d (1) { - ["this"]=> - object(foo)#%d (1) { - ["a"]=> - array(1) { - [0]=> - object(Closure)#%d (1) { - ["this"]=> - *RECURSION* - } - } - } + object(Closure)#%d (0) { } } } @@ -52,21 +41,7 @@ int(1) string(1) "a" array(1) { [0]=> - object(Closure)#%d (1) { - ["this"]=> - object(foo)#%d (1) { - ["a"]=> - array(1) { - [0]=> - object(Closure)#%d (1) { - ["this"]=> - object(foo)#%d (1) { - ["a"]=> - *RECURSION* - } - } - } - } + object(Closure)#%d (0) { } } int(1) diff --git a/Zend/tests/closure_032.phpt b/Zend/tests/closure_032.phpt index dd77dcd5e6..412a923a38 100644 --- a/Zend/tests/closure_032.phpt +++ b/Zend/tests/closure_032.phpt @@ -53,7 +53,6 @@ Array ( [0] => Closure Object ( - [this] => [parameter] => Array ( [$param] => <required> diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 00426e0431..6676c4c5e4 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -37,7 +37,6 @@ typedef struct _zend_closure { zend_object std; zend_function func; - zval *this_ptr; } zend_closure; /* non-static since it needs to be referenced */ @@ -111,13 +110,6 @@ ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC) / } /* }}} */ -ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC) /* {{{ */ -{ - zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC); - return closure->this_ptr; -} -/* }}} */ - static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */ { char *lc_name; @@ -187,10 +179,6 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */ destroy_op_array(&closure->func.op_array TSRMLS_CC); } - if (closure->this_ptr) { - zval_ptr_dtor(&closure->this_ptr); - } - efree(closure); } /* }}} */ @@ -223,17 +211,10 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC); *fptr_ptr = &closure->func; - if (closure->this_ptr) { - if (zobj_ptr) { - *zobj_ptr = closure->this_ptr; - } - *ce_ptr = Z_OBJCE_P(closure->this_ptr); - } else { - if (zobj_ptr) { - *zobj_ptr = NULL; - } - *ce_ptr = closure->func.common.scope; + if (zobj_ptr) { + *zobj_ptr = NULL; } + *ce_ptr = NULL; return SUCCESS; } /* }}} */ @@ -248,13 +229,6 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_ *is_temp = 1; ALLOC_HASHTABLE(rv); zend_hash_init(rv, 1, NULL, ZVAL_PTR_DTOR, 0); - val = closure->this_ptr; - if (!val) { - ALLOC_INIT_ZVAL(val); - } else { - Z_ADDREF_P(val); - } - zend_symtable_update(rv, "this", sizeof("this"), (void *) &val, sizeof(zval *), NULL); if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) { HashTable *static_variables = closure->func.op_array.static_variables; MAKE_STD_ZVAL(val); @@ -369,7 +343,7 @@ static int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, } /* }}} */ -ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zval *this_ptr TSRMLS_DC) /* {{{ */ +ZEND_API void zend_create_closure(zval *res, zend_function *func TSRMLS_DC) /* {{{ */ { zend_closure *closure; @@ -390,19 +364,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent (*closure->func.op_array.refcount)++; } - closure->func.common.scope = scope; - if (scope) { - closure->func.common.fn_flags |= ZEND_ACC_PUBLIC; - if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { - closure->this_ptr = this_ptr; - Z_ADDREF_P(this_ptr); - } else { - closure->func.common.fn_flags |= ZEND_ACC_STATIC; - closure->this_ptr = NULL; - } - } else { - closure->this_ptr = NULL; - } + closure->func.common.scope = NULL; } /* }}} */ diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index c326e329c4..ffbd33f5a7 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -30,11 +30,9 @@ void zend_register_closure_ce(TSRMLS_D); extern ZEND_API zend_class_entry *zend_ce_closure; -ZEND_API void zend_create_closure(zval *res, zend_function *op_array, zend_class_entry *scope, zval *this_ptr TSRMLS_DC); -ZEND_API int zend_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr, zval ***zobj_ptr_ptr TSRMLS_DC); +ZEND_API void zend_create_closure(zval *res, zend_function *op_array TSRMLS_DC); ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC); ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC); -ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC); END_EXTERN_C() diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7f7014b41c..8349ed7ca3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1389,7 +1389,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n CG(labels) = NULL; } -void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC) +void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC) { znode function_name; zend_op_array *current_op_array = CG(active_op_array); @@ -1409,9 +1409,6 @@ void zend_do_begin_lambda_function_declaration(znode *result, znode *function_to zval_dtor(¤t_op->op2.u.constant); ZVAL_LONG(¤t_op->op2.u.constant, zend_hash_func(Z_STRVAL(current_op->op1.u.constant), Z_STRLEN(current_op->op1.u.constant))); current_op->result = *result; - if (is_static) { - CG(active_op_array)->fn_flags |= ZEND_ACC_STATIC; - } CG(active_op_array)->fn_flags |= ZEND_ACC_CLOSURE; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index d9ac44b458..c7b614635b 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -434,7 +434,7 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC); void zend_do_handle_exception(TSRMLS_D); -void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC); +void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC); void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC); void zend_do_try(znode *try_token TSRMLS_DC); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index c46f374c06..3e284e93bf 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -647,10 +647,8 @@ expr_without_variable: | T_ARRAY '(' array_pair_list ')' { $$ = $3; } | '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); } | T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); } - | function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); } + | function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type TSRMLS_CC); } parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; } - | T_STATIC function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); } - parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; } ; function: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0a849f22cb..8e084ad473 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4393,7 +4393,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, CONST) zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); } - zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC); + zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d36ee7b03b..0bc2f73048 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2912,7 +2912,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_CONST_HANDLER( zend_error_noreturn(E_ERROR, "Base lambda function for closure not found"); } - zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC); + zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); } 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(¶m_indent); string_printf(¶m_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(¶m_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, ¶meter) == 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=== |