]> granicus.if.org Git - php/commitdiff
Handlerify get_closure
authorEtienne Kneuss <colder@php.net>
Thu, 14 Aug 2008 21:26:05 +0000 (21:26 +0000)
committerEtienne Kneuss <colder@php.net>
Thu, 14 Aug 2008 21:26:05 +0000 (21:26 +0000)
Zend/zend_API.c
Zend/zend_closures.c
Zend/zend_object_handlers.c
Zend/zend_object_handlers.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 6c62512c275e9e42d731997f2c73b72c6f6cbce9..4db7c79dfa2941797ea968a4cb5c139ff9dfe1f7 100644 (file)
@@ -3238,7 +3238,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval **object_pp, uint ch
                        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) && 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 07062881a2701e68a9c7962339e9e5ed78c21a3b..d4a80719bb5b653043b9ec8b807b1d2dc53c951f 100644 (file)
@@ -212,6 +212,38 @@ static zend_object_value zend_closure_new(zend_class_entry *class_type TSRMLS_DC
 }
 /* }}} */
 
+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) /* {{{ */
+{
+       zend_closure *closure;
+
+       if (Z_TYPE_P(obj) != IS_OBJECT) {
+               return FAILURE;
+       }
+
+       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;
+}
+/* }}} */
+
 void zend_register_closure_ce(TSRMLS_D) /* {{{ */
 {
        zend_class_entry ce;
@@ -233,6 +265,7 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
        closure_handlers.unset_property = zend_closure_unset_property;
        closure_handlers.compare_objects = zend_closure_compare_objects;
        closure_handlers.clone_obj = NULL;
+       closure_handlers.get_closure = zend_closure_get_closure;
 }
 /* }}} */
 
@@ -310,74 +343,6 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
 }
 /* }}} */
 
-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) /* {{{ */
-{
-       zstr key;
-       zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
-
-       if (utype == IS_UNICODE) {
-               key.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
-       } else {
-               key.s = ZEND_INVOKE_FUNC_NAME;
-       }
-
-       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;
-                       }
-                       if (utype == IS_UNICODE) {
-                               efree(key.u);
-                       }
-                       return SUCCESS;
-               } else if (zend_u_hash_find(&ce->function_table, utype, key, 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;
-                               }
-                       }
-                       if (utype == IS_UNICODE) {
-                               efree(key.u);
-                       }
-                       return SUCCESS;
-               }
-       }
-       if (utype == IS_UNICODE) {
-               efree(key.u);
-       }
-       return FAILURE;
-}
-/* }}} */
 
 /*
  * Local variables:
index d7fc4c80e7b21595b34ad243d11aa7009c847c9b..fddf991c133d24ccfe207466c7e126fe4044c67b 100644 (file)
@@ -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
 
@@ -1309,6 +1310,56 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
 }
 /* }}} */
 
+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) /* {{{ */
+{
+       zstr key;
+       zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
+       zend_class_entry *ce;
+
+       if (Z_TYPE_P(obj) != IS_OBJECT) {
+               return FAILURE;
+       }
+
+       ce = Z_OBJCE_P(obj);
+
+       if (utype == IS_UNICODE) {
+               key.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
+       } else {
+               key.s = ZEND_INVOKE_FUNC_NAME;
+       }
+
+       if (zend_u_hash_find(&ce->function_table, utype, key, sizeof(ZEND_INVOKE_FUNC_NAME), (void**)fptr_ptr) == FAILURE) {
+               if (utype == IS_UNICODE) {
+                       efree(key.u);
+               }
+               return FAILURE;
+       }
+
+       *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;
+               }
+       }
+
+       if (utype == IS_UNICODE) {
+               efree(key.u);
+       }
+
+       return SUCCESS;
+}
+/* }}} */
+
 ZEND_API zend_object_handlers std_object_handlers = {
        zend_objects_store_add_ref,                             /* add_ref */
        zend_objects_store_del_ref,                             /* del_ref */
@@ -1334,7 +1385,8 @@ ZEND_API zend_object_handlers std_object_handlers = {
        zend_std_compare_objects,                               /* compare_objects */
        zend_std_cast_object_tostring,                  /* cast_object */
        NULL,                                                                   /* count_elements */
-       NULL,                                   /* get_debug_info */
+       NULL,                                                                   /* get_debug_info */
+       zend_std_get_closure,                                   /* get_closure */
 };
 
 /*
index f85e025aea012f98549b6af76fb4a4eb0f088ed1..6c24c263cb7ab71ed9e761a24098c4316bf7631f 100644 (file)
@@ -108,6 +108,8 @@ typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type, void *e
  * 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 +137,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 19c8b87e42b56617cd7d940fd65bdefd12504000..0b975dd19c88334a0562f73e1182f4b1f36c9e04 100644 (file)
@@ -2131,7 +2131,8 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
                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) &&
+                       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));
                        }
index 4c884f2d8ec54311c50057c7ad161bc5a2bfca24..a5dd6417d2cb1c75cb7ed92fc59a97e89db66117 100644 (file)
@@ -763,7 +763,8 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
                function_name = &opline->op2.u.constant;
 
                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) &&
+                       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));
                        }
@@ -962,7 +963,8 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
                function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
                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) &&
+                       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));
                        }
@@ -1049,7 +1051,8 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
                function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
                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) &&
+                       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));
                        }
@@ -1165,7 +1168,8 @@ static int ZEND_FASTCALL  ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
                function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
                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) &&
+                       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));
                        }