]> granicus.if.org Git - php/commitdiff
- Made closures implementation reflection friendly (Christian)
authorDmitry Stogov <dmitry@php.net>
Mon, 11 Aug 2008 08:49:14 +0000 (08:49 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 11 Aug 2008 08:49:14 +0000 (08:49 +0000)
- Changed E_ERROR(s) into E_RECOVERABLE_ERROR(s) (Marcus)

Zend/tests/closure_022.phpt
Zend/zend_closures.c
Zend/zend_closures.h

index 25fbe931d8ad31596343caa30bcebda8de6e8f7a..8621d2c095f9c1e2edc2a53d81b3726f8c3940e4 100755 (executable)
@@ -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
 
index 7562df33b07689a5611e54bd2f79763acda9af61..07062881a2701e68a9c7962339e9e5ed78c21a3b 100644 (file)
 #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,7 @@ typedef struct _zend_closure {
        zval          *this_ptr;
 } zend_closure;
 
-static zend_class_entry *zend_ce_closure;
+ZEND_API zend_class_entry *zend_ce_closure;
 static zend_object_handlers closure_handlers;
 
 ZEND_METHOD(Closure, __invoke) /* {{{ */
@@ -50,7 +49,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 +73,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, int *type, zstr *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, int type, const zstr 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 +98,26 @@ 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;
+       if (UG(unicode)) {
+               invoke->internal_function.function_name.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
+       } else {
+               invoke->internal_function.function_name.s = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
+       }
+       return invoke;
+}
+/* }}} */
+
 static zend_function *zend_closure_get_method(zval **object_ptr, zstr method_name, int method_len TSRMLS_DC) /* {{{ */
 {
        unsigned int lc_name_len;
@@ -110,22 +129,8 @@ static zend_function *zend_closure_get_method(zval **object_ptr, zstr method_nam
        if ((lc_name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
                (ZEND_U_EQUAL(type, lc_name, lc_name_len, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))
        ) {
-               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;
-               if (UG(unicode)) {
-                       invoke->internal_function.function_name.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
-               } else {
-                       invoke->internal_function.function_name.s = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
-               }
                efree(lc_name.v);
-               return invoke;
+               return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC);
        }
        efree(lc_name.v);
        return NULL;
index c3a3b87095fb98bef46fc47befecb215cff98e9e..104977eb6bda8db0190a509bfe67fe7333f9b81e 100644 (file)
 
 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()