Index: Zend/zend_object_handlers.c =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.c,v retrieving revision 1.135.2.6.2.22.2.18 diff -u -p -r1.135.2.6.2.22.2.18 zend_object_handlers.c --- Zend/zend_object_handlers.c 26 Jul 2008 13:14:00 -0000 1.135.2.6.2.22.2.18 +++ Zend/zend_object_handlers.c 3 Aug 2008 21:42:39 -0000 @@ -27,6 +27,7 @@ #include "zend_objects_API.h" #include "zend_object_handlers.h" #include "zend_interfaces.h" +#include "zend_closures.h" #define DEBUG_OBJECT_HANDLERS 0 @@ -1261,6 +1262,33 @@ ZEND_API int zend_std_cast_object_tostri } /* }}} */ +int zend_std_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr, zval ***zobj_ptr_ptr TSRMLS_DC) { /* {{{ */ + if (Z_TYPE_P(obj) == IS_OBJECT) { + zend_class_entry *ce = Z_OBJCE_P(obj); + if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void**)fptr_ptr) == SUCCESS) { + *ce_ptr = ce; + if ((*fptr_ptr)->common.fn_flags & ZEND_ACC_STATIC) { + if (zobj_ptr) { + *zobj_ptr = NULL; + } + if (zobj_ptr_ptr) { + *zobj_ptr_ptr = NULL; + } + } else { + if (zobj_ptr) { + *zobj_ptr = obj; + } + if (zobj_ptr_ptr) { + *zobj_ptr_ptr = NULL; + } + } + return SUCCESS; + } + } + return FAILURE; +} +/* }}} */ + ZEND_API zend_object_handlers std_object_handlers = { zend_objects_store_add_ref, /* add_ref */ zend_objects_store_del_ref, /* del_ref */ @@ -1287,6 +1315,7 @@ ZEND_API zend_object_handlers std_object zend_std_cast_object_tostring, /* cast_object */ NULL, /* count_elements */ NULL, /* get_debug_info */ + zend_std_get_closure, /* get_closure */ }; /* Index: Zend/zend_object_handlers.h =================================================================== RCS file: /repository/ZendEngine2/zend_object_handlers.h,v retrieving revision 1.47.2.2.2.5.2.3 diff -u -p -r1.47.2.2.2.5.2.3 zend_object_handlers.h --- Zend/zend_object_handlers.h 31 Dec 2007 07:17:04 -0000 1.47.2.2.2.5.2.3 +++ Zend/zend_object_handlers.h 3 Aug 2008 21:42:39 -0000 @@ -108,6 +108,9 @@ typedef int (*zend_object_cast_t)(zval * * Returns FAILURE if the object does not have any sense of overloaded dimensions */ typedef int (*zend_object_count_elements_t)(zval *object, long *count TSRMLS_DC); + +typedef int (*zend_object_get_closure_t)(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr, zval ***zobj_ptr_ptr TSRMLS_DC); + struct _zend_object_handlers { /* general object functions */ zend_object_add_ref_t add_ref; @@ -135,6 +138,7 @@ struct _zend_object_handlers { zend_object_cast_t cast_object; zend_object_count_elements_t count_elements; zend_object_get_debug_info_t get_debug_info; + zend_object_get_closure_t get_closure; }; extern ZEND_API zend_object_handlers std_object_handlers; Index: Zend/zend_closures.c =================================================================== RCS file: /repository/ZendEngine2/zend_closures.c,v retrieving revision 1.3.2.9 diff -u -p -r1.3.2.9 zend_closures.c --- Zend/zend_closures.c 31 Jul 2008 07:10:33 -0000 1.3.2.9 +++ Zend/zend_closures.c 3 Aug 2008 21:42:39 -0000 @@ -26,7 +26,6 @@ #include "zend_objects_API.h" #include "zend_globals.h" -#define ZEND_INVOKE_FUNC_NAME "__invoke" #define ZEND_CLOSURE_PRINT_NAME "Closure object" #define ZEND_CLOSURE_PROPERTY_ERROR() \ @@ -188,11 +187,45 @@ static zend_object_value zend_closure_ne } /* }}} */ +const zend_function_entry zend_funcs_closure[] = { + ZEND_ME(Closure, __invoke, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr, zval ***zobj_ptr_ptr TSRMLS_DC) /* {{{ */ +{ + if (Z_TYPE_P(obj) == IS_OBJECT) { + zend_closure *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; + } + if (zobj_ptr_ptr) { + *zobj_ptr_ptr = &closure->this_ptr; + } + *ce_ptr = Z_OBJCE_P(closure->this_ptr); + } else { + if (zobj_ptr) { + *zobj_ptr = NULL; + } + if (zobj_ptr_ptr) { + *zobj_ptr_ptr = NULL; + } + *ce_ptr = closure->func.common.scope; + } + return SUCCESS; + } + return FAILURE; +} +/* }}} */ + void zend_register_closure_ce(TSRMLS_D) /* {{{ */ { zend_class_entry ce; - INIT_CLASS_ENTRY(ce, "Closure", NULL); + INIT_CLASS_ENTRY(ce, "Closure", zend_funcs_closure); zend_ce_closure = zend_register_internal_class(&ce TSRMLS_CC); zend_ce_closure->ce_flags |= ZEND_ACC_FINAL_CLASS; zend_ce_closure->create_object = zend_closure_new; @@ -206,6 +239,7 @@ void zend_register_closure_ce(TSRMLS_D) closure_handlers.has_property = zend_closure_has_property; closure_handlers.unset_property = zend_closure_unset_property; closure_handlers.compare_objects = zend_closure_compare_objects; + closure_handlers.get_closure = zend_closure_get_closure; closure_handlers.clone_obj = NULL; } /* }}} */ @@ -284,57 +318,6 @@ ZEND_API void zend_create_closure(zval * } /* }}} */ -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) /* {{{ */ -{ - if (Z_TYPE_P(obj) == IS_OBJECT) { - zend_class_entry *ce = Z_OBJCE_P(obj); - - if (ce == zend_ce_closure) { - zend_closure *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; - } - if (zobj_ptr_ptr) { - *zobj_ptr_ptr = &closure->this_ptr; - } - *ce_ptr = Z_OBJCE_P(closure->this_ptr); - } else { - if (zobj_ptr) { - *zobj_ptr = NULL; - } - if (zobj_ptr_ptr) { - *zobj_ptr_ptr = NULL; - } - *ce_ptr = closure->func.common.scope; - } - return SUCCESS; - } else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void**)fptr_ptr) == SUCCESS) { - *ce_ptr = ce; - if ((*fptr_ptr)->common.fn_flags & ZEND_ACC_STATIC) { - if (zobj_ptr) { - *zobj_ptr = NULL; - } - if (zobj_ptr_ptr) { - *zobj_ptr_ptr = NULL; - } - } else { - if (zobj_ptr) { - *zobj_ptr = obj; - } - if (zobj_ptr_ptr) { - *zobj_ptr_ptr = NULL; - } - } - return SUCCESS; - } - } - return FAILURE; -} -/* }}} */ - /* * Local variables: * tab-width: 4 Index: Zend/zend_closures.h =================================================================== RCS file: /repository/ZendEngine2/zend_closures.h,v retrieving revision 1.1.2.2 diff -u -p -r1.1.2.2 zend_closures.h --- Zend/zend_closures.h 14 Jul 2008 09:48:59 -0000 1.1.2.2 +++ Zend/zend_closures.h 3 Aug 2008 21:42:39 -0000 @@ -22,6 +22,8 @@ #ifndef ZEND_CLOSURES_H #define ZEND_CLOSURES_H +#define ZEND_INVOKE_FUNC_NAME "__invoke" + BEGIN_EXTERN_C() void zend_register_closure_ce(TSRMLS_D); Index: Zend/zend_API.c =================================================================== RCS file: /repository/ZendEngine2/zend_API.c,v retrieving revision 1.296.2.27.2.34.2.46 diff -u -p -r1.296.2.27.2.34.2.46 zend_API.c --- Zend/zend_API.c 2 Aug 2008 04:46:05 -0000 1.296.2.27.2.34.2.46 +++ Zend/zend_API.c 3 Aug 2008 21:42:39 -0000 @@ -2716,7 +2716,7 @@ ZEND_API zend_bool zend_is_callable_ex(z return 0; case IS_OBJECT: - if (zend_get_closure(callable, &fcc->calling_scope, &fcc->function_handler, NULL, &fcc->object_pp TSRMLS_CC) == SUCCESS) { + if (Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, NULL, &fcc->object_pp TSRMLS_CC) == SUCCESS) { fcc->called_scope = fcc->calling_scope; if (callable_name) { zend_class_entry *ce = Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */ Index: Zend/zend_vm_def.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_def.h,v retrieving revision 1.59.2.29.2.48.2.65 diff -u -p -r1.59.2.29.2.48.2.65 zend_vm_def.h --- Zend/zend_vm_def.h 26 Jul 2008 15:30:25 -0000 1.59.2.29.2.48.2.65 +++ Zend/zend_vm_def.h 3 Aug 2008 21:42:40 -0000 @@ -2069,7 +2069,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_N function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); if (Z_TYPE_P(function_name) == IS_OBJECT && - zend_get_closure(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object), NULL TSRMLS_CC) == SUCCESS) { if (EX(object)) { Z_ADDREF_P(EX(object)); }