diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-08-11 08:49:00 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-08-11 08:49:00 +0000 |
commit | a4a3ed44bb065ea854830c51b828242c4f47b073 (patch) | |
tree | 030ba0de7bc6056eb3124ba6015623496c961ee0 /Zend | |
parent | 8526b7828656a8a192e8b1c6dd74db2aaa8b63e5 (diff) | |
download | php-git-a4a3ed44bb065ea854830c51b828242c4f47b073.tar.gz |
- Made closures implementation reflection friendly (Christian)
- Changed E_ERROR(s) into E_RECOVERABLE_ERROR(s) (Marcus)
Diffstat (limited to 'Zend')
-rwxr-xr-x | Zend/tests/closure_022.phpt | 2 | ||||
-rw-r--r-- | Zend/zend_closures.c | 43 | ||||
-rw-r--r-- | Zend/zend_closures.h | 5 |
3 files changed, 31 insertions, 19 deletions
diff --git a/Zend/tests/closure_022.phpt b/Zend/tests/closure_022.phpt index 25fbe931d8..8621d2c095 100755 --- a/Zend/tests/closure_022.phpt +++ b/Zend/tests/closure_022.phpt @@ -8,5 +8,5 @@ $foo = function() use ($a) { $foo->a = 1; ?> --EXPECTF-- -Fatal error: Closure object cannot have properties in %sclosure_022.php on line 5 +Catchable fatal error: Closure object cannot have properties in %sclosure_022.php on line 5 diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 130ce0c4bb..88a8bf6d82 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -26,11 +26,10 @@ #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() \ - zend_error(E_ERROR, "Closure object cannot have properties") + zend_error(E_RECOVERABLE_ERROR, "Closure object cannot have properties") typedef struct _zend_closure { zend_object std; @@ -38,7 +37,8 @@ typedef struct _zend_closure { zval *this_ptr; } zend_closure; -static zend_class_entry *zend_ce_closure; +/* non-static since it needs to be referenced */ +ZEND_API zend_class_entry *zend_ce_closure; static zend_object_handlers closure_handlers; ZEND_METHOD(Closure, __invoke) /* {{{ */ @@ -50,7 +50,7 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */ arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS()); if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) { efree(arguments); - zend_error(E_ERROR, "Cannot get arguments for calling closure"); + zend_error(E_RECOVERABLE_ERROR, "Cannot get arguments for calling closure"); RETVAL_FALSE; } else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) { RETVAL_FALSE; @@ -74,21 +74,21 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */ static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */ { - zend_error(E_ERROR, "Instantiation of 'Closure' is not allowed"); + zend_error(E_RECOVERABLE_ERROR, "Instantiation of 'Closure' is not allowed"); return NULL; } /* }}} */ static int zend_closure_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */ { - zend_error(E_ERROR, "Serialization of 'Closure' is not allowed"); + zend_error(E_RECOVERABLE_ERROR, "Serialization of 'Closure' is not allowed"); return FAILURE; } /* }}} */ static int zend_closure_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */ { - zend_error(E_ERROR, "Unserialization of 'Closure' is not allowed"); + zend_error(E_RECOVERABLE_ERROR, "Unserialization of 'Closure' is not allowed"); return FAILURE; } /* }}} */ @@ -99,6 +99,23 @@ static int zend_closure_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ } /* }}} */ +ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {{{ */ +{ + zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC); + zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function)); + + invoke->common = closure->func.common; + invoke->type = ZEND_INTERNAL_FUNCTION; + invoke->internal_function.fn_flags = ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER; + invoke->internal_function.handler = ZEND_MN(Closure___invoke); + invoke->internal_function.module = 0; + invoke->internal_function.scope = zend_ce_closure; + invoke->internal_function.function_name = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1); + return invoke; + +} +/* }}} */ + static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */ { char *lc_name; @@ -109,18 +126,8 @@ static zend_function *zend_closure_get_method(zval **object_ptr, char *method_na if ((method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0 ) { - zend_closure *closure = (zend_closure *)zend_object_store_get_object(*object_ptr TSRMLS_CC); - zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function)); - - invoke->common = closure->func.common; - invoke->type = ZEND_INTERNAL_FUNCTION; - invoke->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER; - invoke->internal_function.handler = ZEND_MN(Closure___invoke); - invoke->internal_function.module = 0; - invoke->internal_function.scope = zend_ce_closure; - invoke->internal_function.function_name = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1); free_alloca(lc_name, use_heap); - return invoke; + return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC); } free_alloca(lc_name, use_heap); return NULL; diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index c3a3b87095..104977eb6b 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -24,10 +24,15 @@ BEGIN_EXTERN_C() +#define ZEND_INVOKE_FUNC_NAME "__invoke" + void zend_register_closure_ce(TSRMLS_D); +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 zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC); END_EXTERN_C() |