From 6423606a634c6bbc41ca0b41e36342fd8f501d69 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss Date: Thu, 14 Aug 2008 21:26:05 +0000 Subject: [PATCH] Handlerify get_closure --- Zend/zend_API.c | 2 +- Zend/zend_closures.c | 101 ++++++++++++------------------------ Zend/zend_object_handlers.c | 54 ++++++++++++++++++- Zend/zend_object_handlers.h | 3 ++ Zend/zend_vm_def.h | 3 +- Zend/zend_vm_execute.h | 12 +++-- 6 files changed, 100 insertions(+), 75 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 6c62512c27..4db7c79dfa 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -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? */ diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 07062881a2..d4a80719bb 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -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: diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index d7fc4c80e7..fddf991c13 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -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 */ }; /* diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index f85e025aea..6c24c263cb 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -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; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 19c8b87e42..0b975dd19c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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)); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4c884f2d8e..a5dd6417d2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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)); } -- 2.40.0