Browse Source

Handlerify get_closure

experimental/first_unicode_implementation
Etienne Kneuss 18 years ago
parent
commit
6423606a63
  1. 2
      Zend/zend_API.c
  2. 101
      Zend/zend_closures.c
  3. 54
      Zend/zend_object_handlers.c
  4. 3
      Zend/zend_object_handlers.h
  5. 3
      Zend/zend_vm_def.h
  6. 12
      Zend/zend_vm_execute.h

2
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? */

101
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:

54
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 */
};
/*

3
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;

3
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));
}

12
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));
}

Loading…
Cancel
Save