cseiler Mon Jan 26 22:54:41 2009 UTC Removed files: (Branch: PHP_5_3) /ZendEngine2/tests closure_005.phpt closure_007.phpt /php-src/ext/reflection/tests 027.phpt ReflectionFunction_getClosure_basic.phpt ReflectionFunction_getClosure_error.phpt ReflectionMethod_getClosure_basic.phpt ReflectionMethod_getClosure_error.phpt closures_004.phpt
Modified files: /ZendEngine2 zend_closures.c zend_closures.h zend_compile.c zend_compile.h zend_language_parser.y zend_vm_def.h zend_vm_execute.h /ZendEngine2/tests closure_020.phpt closure_026.phpt closure_032.phpt /php-src/ext/reflection php_reflection.c /php-src/ext/reflection/tests closures_001.phpt closures_002.phpt closures_003.phpt Log: [DOC] Remove $this support in closures for PHP 5.3 beta 1 - Implementation notes here: http://wiki.php.net/rfc/closures/removal-of-this
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_closures.c?r1=1.3.2.25&r2=1.3.2.26&diff_format=u Index: ZendEngine2/zend_closures.c diff -u ZendEngine2/zend_closures.c:1.3.2.25 ZendEngine2/zend_closures.c:1.3.2.26 --- ZendEngine2/zend_closures.c:1.3.2.25 Wed Jan 14 10:28:22 2009 +++ ZendEngine2/zend_closures.c Mon Jan 26 22:54:18 2009 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_closures.c,v 1.3.2.25 2009/01/14 10:28:22 dmitry Exp $ */ +/* $Id: zend_closures.c,v 1.3.2.26 2009/01/26 22:54:18 cseiler Exp $ */ #include "zend.h" #include "zend_API.h" @@ -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 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 @@ 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 @@ 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 @@ *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 @@ } /* }}} */ -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 @@ (*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; } /* }}} */ http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_closures.h?r1=1.1.2.7&r2=1.1.2.8&diff_format=u Index: ZendEngine2/zend_closures.h diff -u ZendEngine2/zend_closures.h:1.1.2.7 ZendEngine2/zend_closures.h:1.1.2.8 --- ZendEngine2/zend_closures.h:1.1.2.7 Wed Jan 14 10:28:22 2009 +++ ZendEngine2/zend_closures.h Mon Jan 26 22:54:19 2009 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_closures.h,v 1.1.2.7 2009/01/14 10:28:22 dmitry Exp $ */ +/* $Id: zend_closures.h,v 1.1.2.8 2009/01/26 22:54:19 cseiler Exp $ */ #ifndef ZEND_CLOSURES_H #define ZEND_CLOSURES_H @@ -30,11 +30,9 @@ 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() http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.647.2.27.2.41.2.101&r2=1.647.2.27.2.41.2.102&diff_format=u Index: ZendEngine2/zend_compile.c diff -u ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.101 ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.102 --- ZendEngine2/zend_compile.c:1.647.2.27.2.41.2.101 Tue Jan 20 13:21:44 2009 +++ ZendEngine2/zend_compile.c Mon Jan 26 22:54:19 2009 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.101 2009/01/20 13:21:44 dmitry Exp $ */ +/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.102 2009/01/26 22:54:19 cseiler Exp $ */ #include <zend_language_parser.h> #include "zend.h" @@ -1389,7 +1389,7 @@ 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 @@ 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; } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.h?r1=1.316.2.8.2.12.2.38&r2=1.316.2.8.2.12.2.39&diff_format=u Index: ZendEngine2/zend_compile.h diff -u ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.38 ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.39 --- ZendEngine2/zend_compile.h:1.316.2.8.2.12.2.38 Tue Jan 20 13:21:46 2009 +++ ZendEngine2/zend_compile.h Mon Jan 26 22:54:20 2009 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.38 2009/01/20 13:21:46 dmitry Exp $ */ +/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.39 2009/01/26 22:54:20 cseiler Exp $ */ #ifndef ZEND_COMPILE_H #define ZEND_COMPILE_H @@ -434,7 +434,7 @@ 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); http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_parser.y?r1=1.160.2.4.2.8.2.33&r2=1.160.2.4.2.8.2.34&diff_format=u Index: ZendEngine2/zend_language_parser.y diff -u ZendEngine2/zend_language_parser.y:1.160.2.4.2.8.2.33 ZendEngine2/zend_language_parser.y:1.160.2.4.2.8.2.34 --- ZendEngine2/zend_language_parser.y:1.160.2.4.2.8.2.33 Fri Jan 2 20:45:41 2009 +++ ZendEngine2/zend_language_parser.y Mon Jan 26 22:54:20 2009 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_parser.y,v 1.160.2.4.2.8.2.33 2009/01/02 20:45:41 felipe Exp $ */ +/* $Id: zend_language_parser.y,v 1.160.2.4.2.8.2.34 2009/01/26 22:54:20 cseiler Exp $ */ /* * LALR shift/reduce conflicts and how they are resolved: @@ -647,10 +647,8 @@ | 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: http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.83&r2=1.59.2.29.2.48.2.84&diff_format=u Index: ZendEngine2/zend_vm_def.h diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.83 ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.84 --- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.83 Tue Jan 20 13:21:46 2009 +++ ZendEngine2/zend_vm_def.h Mon Jan 26 22:54:20 2009 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.83 2009/01/20 13:21:46 dmitry Exp $ */ +/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.84 2009/01/26 22:54:20 cseiler Exp $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -4393,7 +4393,7 @@ 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(); } http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.83&r2=1.62.2.30.2.49.2.84&diff_format=u Index: ZendEngine2/zend_vm_execute.h diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.83 ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.84 --- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.83 Tue Jan 20 13:21:46 2009 +++ ZendEngine2/zend_vm_execute.h Mon Jan 26 22:54:22 2009 @@ -2912,7 +2912,7 @@ 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(); } http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/closure_020.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u Index: ZendEngine2/tests/closure_020.phpt diff -u ZendEngine2/tests/closure_020.phpt:1.1.2.2 ZendEngine2/tests/closure_020.phpt:1.1.2.3 --- ZendEngine2/tests/closure_020.phpt:1.1.2.2 Thu Jan 1 16:22:44 2009 +++ ZendEngine2/tests/closure_020.phpt Mon Jan 26 22:54:32 2009 @@ -27,22 +27,7 @@ ["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 @@ ["test":"foo":private]=> int(3) ["a"]=> - object(Closure)#%d (2) { - ["this"]=> - *RECURSION* + object(Closure)#%d (1) { ["static"]=> array(1) { ["a"]=> http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/closure_026.phpt?r1=1.1.2.3&r2=1.1.2.4&diff_format=u Index: ZendEngine2/tests/closure_026.phpt diff -u ZendEngine2/tests/closure_026.phpt:1.1.2.3 ZendEngine2/tests/closure_026.phpt:1.1.2.4 --- ZendEngine2/tests/closure_026.phpt:1.1.2.3 Thu Jan 1 16:22:44 2009 +++ ZendEngine2/tests/closure_026.phpt Mon Jan 26 22:54:32 2009 @@ -32,18 +32,7 @@ ["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 @@ 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) http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/closure_032.phpt?r1=1.1.2.3&r2=1.1.2.4&diff_format=u Index: ZendEngine2/tests/closure_032.phpt diff -u ZendEngine2/tests/closure_032.phpt:1.1.2.3 ZendEngine2/tests/closure_032.phpt:1.1.2.4 --- ZendEngine2/tests/closure_032.phpt:1.1.2.3 Thu Jan 1 16:22:44 2009 +++ ZendEngine2/tests/closure_032.phpt Mon Jan 26 22:54:32 2009 @@ -53,7 +53,6 @@ ( [0] => Closure Object ( - [this] => [parameter] => Array ( [$param] => <required> http://cvs.php.net/viewvc.cgi/php-src/ext/reflection/php_reflection.c?r1=1.164.2.33.2.45.2.51&r2=1.164.2.33.2.45.2.52&diff_format=u Index: php-src/ext/reflection/php_reflection.c diff -u php-src/ext/reflection/php_reflection.c:1.164.2.33.2.45.2.51 php-src/ext/reflection/php_reflection.c:1.164.2.33.2.45.2.52 --- php-src/ext/reflection/php_reflection.c:1.164.2.33.2.45.2.51 Wed Jan 7 22:40:16 2009 +++ php-src/ext/reflection/php_reflection.c Mon Jan 26 22:54:33 2009 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_reflection.c,v 1.164.2.33.2.45.2.51 2009/01/07 22:40:16 felipe Exp $ */ +/* $Id: php_reflection.c,v 1.164.2.33.2.45.2.52 2009/01/26 22:54:33 cseiler Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -326,7 +326,7 @@ } 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 @@ && ((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 @@ 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 @@ } /* }}} */ +/* {{{ _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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ /* }}} */ /* {{{ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } /* }}} */ -/* {{{ 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 @@ 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 @@ 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 @@ && 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { /* 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 @@ 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 @@ 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 @@ 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 @@ && 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 @@ { 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 @@ } 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 @@ 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 @@ 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 @@ 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) @@ -5511,7 +5429,7 @@ php_info_print_table_start(); php_info_print_table_header(2, "Reflection", "enabled"); - php_info_print_table_row(2, "Version", "$Revision: 1.164.2.33.2.45.2.51 $"); + php_info_print_table_row(2, "Version", "$Revision: 1.164.2.33.2.45.2.52 $"); php_info_print_table_end(); } /* }}} */ @@ -5525,7 +5443,7 @@ NULL, NULL, PHP_MINFO(reflection), - "$Revision: 1.164.2.33.2.45.2.51 $", + "$Revision: 1.164.2.33.2.45.2.52 $", STANDARD_MODULE_PROPERTIES }; /* }}} */ http://cvs.php.net/viewvc.cgi/php-src/ext/reflection/tests/closures_001.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u Index: php-src/ext/reflection/tests/closures_001.phpt diff -u php-src/ext/reflection/tests/closures_001.phpt:1.1.2.2 php-src/ext/reflection/tests/closures_001.phpt:1.1.2.3 --- php-src/ext/reflection/tests/closures_001.phpt:1.1.2.2 Mon Aug 11 12:43:21 2008 +++ php-src/ext/reflection/tests/closures_001.phpt Mon Jan 26 22:54:33 2009 @@ -19,7 +19,7 @@ echo "---\n"; -$rm = new ReflectionMethod($closure); +$rm = new ReflectionMethod($closure, '__invoke'); var_dump($rm->getName()); var_dump($rm->getNumberOfParameters()); var_dump($rm->getNumberOfRequiredParameters()); http://cvs.php.net/viewvc.cgi/php-src/ext/reflection/tests/closures_002.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u Index: php-src/ext/reflection/tests/closures_002.phpt diff -u php-src/ext/reflection/tests/closures_002.phpt:1.1.2.2 php-src/ext/reflection/tests/closures_002.phpt:1.1.2.3 --- php-src/ext/reflection/tests/closures_002.phpt:1.1.2.2 Mon Aug 11 12:43:21 2008 +++ php-src/ext/reflection/tests/closures_002.phpt Mon Jan 26 22:54:34 2009 @@ -7,15 +7,15 @@ 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()); ?> http://cvs.php.net/viewvc.cgi/php-src/ext/reflection/tests/closures_003.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u Index: php-src/ext/reflection/tests/closures_003.phpt diff -u php-src/ext/reflection/tests/closures_003.phpt:1.1.2.2 php-src/ext/reflection/tests/closures_003.phpt:1.1.2.3 --- php-src/ext/reflection/tests/closures_003.phpt:1.1.2.2 Mon Aug 11 22:31:22 2008 +++ php-src/ext/reflection/tests/closures_003.phpt Mon Jan 26 22:54:34 2009 @@ -5,14 +5,14 @@ $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";
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php