]> granicus.if.org Git - php/commitdiff
[DOC] Remove $this support in closures for PHP 5.3 beta 1
authorChristian Seiler <cseiler@php.net>
Mon, 26 Jan 2009 22:54:34 +0000 (22:54 +0000)
committerChristian Seiler <cseiler@php.net>
Mon, 26 Jan 2009 22:54:34 +0000 (22:54 +0000)
- Implementation notes here:
  http://wiki.php.net/rfc/closures/removal-of-this

22 files changed:
Zend/tests/closure_005.phpt [deleted file]
Zend/tests/closure_007.phpt [deleted file]
Zend/tests/closure_020.phpt
Zend/tests/closure_026.phpt
Zend/tests/closure_032.phpt
Zend/zend_closures.c
Zend/zend_closures.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/reflection/php_reflection.c
ext/reflection/tests/027.phpt [deleted file]
ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt [deleted file]
ext/reflection/tests/ReflectionFunction_getClosure_error.phpt [deleted file]
ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt [deleted file]
ext/reflection/tests/ReflectionMethod_getClosure_error.phpt [deleted file]
ext/reflection/tests/closures_001.phpt
ext/reflection/tests/closures_002.phpt
ext/reflection/tests/closures_003.phpt
ext/reflection/tests/closures_004.phpt [deleted file]

diff --git a/Zend/tests/closure_005.phpt b/Zend/tests/closure_005.phpt
deleted file mode 100644 (file)
index 4e32faa..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
---TEST--
-Closure 005: Lambda inside class, lifetime of $this
---FILE--
-<?php
-
-class A {
-       private $x;
-
-       function __construct($x) {
-               $this->x = $x;
-       }
-
-       function __destruct() {
-               echo "Destroyed\n";
-       }
-
-       function getIncer($val) {
-               return function() use ($val) {
-                       $this->x += $val;
-               };
-       }
-
-       function getPrinter() {
-               return function() {
-                       echo $this->x."\n";
-               };
-       }
-       
-       function getError() {
-               return static function() {
-                       echo $this->x."\n";
-               };
-       }
-       
-       function printX() {
-               echo $this->x."\n";
-       }
-}
-
-$a = new A(3);
-$incer = $a->getIncer(2);
-$printer = $a->getPrinter();
-$error = $a->getError();
-
-$a->printX();
-$printer();
-$incer();
-$a->printX();
-$printer();
-
-unset($a);
-
-$incer();
-$printer();
-
-unset($incer);
-$printer();
-
-unset($printer);
-
-$error();
-
-echo "Done\n";
-?>
---EXPECTF--
-3
-3
-5
-5
-7
-7
-Destroyed
-
-Fatal error: Using $this when not in object context in %sclosure_005.php on line 28
diff --git a/Zend/tests/closure_007.phpt b/Zend/tests/closure_007.phpt
deleted file mode 100644 (file)
index 89cd06d..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
---TEST--
-Closure 007: Nested lambdas in classes
---FILE--
-<?php
-
-class A {
-       private $x = 0;
-
-       function getClosureGetter () {
-               return function () {
-                       return function () {
-                               $this->x++;
-                       };
-               };
-       }
-
-       function printX () {
-               echo $this->x."\n";
-       }
-}
-
-$a = new A;
-$a->printX();
-$getClosure = $a->getClosureGetter();
-$a->printX();
-$closure = $getClosure();
-$a->printX();
-$closure();
-$a->printX();
-
-echo "Done\n";
-?>
---EXPECT--
-0
-0
-0
-1
-Done
index e34360d63ed85d4ae5c73fc67b3a5930d9358839..7b4c60b9bdff46ac44b69ab73ded3ca0bc4c6588 100644 (file)
@@ -27,22 +27,7 @@ object(foo)#%d (%d) {
   ["test":"foo":private]=>
   int(3)
   ["a"]=>
-  object(Closure)#%d (2) {
-    ["this"]=>
-    object(foo)#%d (2) {
-      ["test":"foo":private]=>
-      int(3)
-      ["a"]=>
-      object(Closure)#%d (2) {
-        ["this"]=>
-        *RECURSION*
-        ["static"]=>
-        array(1) {
-          ["a"]=>
-          *RECURSION*
-        }
-      }
-    }
+  object(Closure)#%d (1) {
     ["static"]=>
     array(1) {
       ["a"]=>
@@ -50,9 +35,7 @@ object(foo)#%d (%d) {
         ["test":"foo":private]=>
         int(3)
         ["a"]=>
-        object(Closure)#%d (2) {
-          ["this"]=>
-          *RECURSION*
+        object(Closure)#%d (1) {
           ["static"]=>
           array(1) {
             ["a"]=>
index 87829a33a2d0cf625ff58e1c37ceb512ae7ed01e..f9e6bd5e257b9570330bcc33f8dd0ef9b5fd94a7 100644 (file)
@@ -32,18 +32,7 @@ object(foo)#%d (1) {
   ["a"]=>
   array(1) {
     [0]=>
-    object(Closure)#%d (1) {
-      ["this"]=>
-      object(foo)#%d (1) {
-        ["a"]=>
-        array(1) {
-          [0]=>
-          object(Closure)#%d (1) {
-            ["this"]=>
-            *RECURSION*
-          }
-        }
-      }
+    object(Closure)#%d (0) {
     }
   }
 }
@@ -52,21 +41,7 @@ int(1)
 string(1) "a"
 array(1) {
   [0]=>
-  object(Closure)#%d (1) {
-    ["this"]=>
-    object(foo)#%d (1) {
-      ["a"]=>
-      array(1) {
-        [0]=>
-        object(Closure)#%d (1) {
-          ["this"]=>
-          object(foo)#%d (1) {
-            ["a"]=>
-            *RECURSION*
-          }
-        }
-      }
-    }
+  object(Closure)#%d (0) {
   }
 }
 int(1)
index dd77dcd5e6a3d807995fdfdd746880760439890a..412a923a38c52a741c12390b6c7554ddbdf1bf71 100644 (file)
@@ -53,7 +53,6 @@ Array
                 (
                     [0] => Closure Object
                         (
-                            [this] => 
                             [parameter] => Array
                                 (
                                     [$param] => <required>
index 00426e0431cdb5ef26e5917482599ac1aaf6bb09..6676c4c5e430d1459fe549e4c2afb98c412840f7 100644 (file)
@@ -37,7 +37,6 @@
 typedef struct _zend_closure {
        zend_object    std;
        zend_function  func;
-       zval          *this_ptr;
 } zend_closure;
 
 /* non-static since it needs to be referenced */
@@ -111,13 +110,6 @@ ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC) /
 }
 /* }}} */
 
-ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC) /* {{{ */
-{
-       zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);    
-       return closure->this_ptr;
-}
-/* }}} */
-
 static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */
 {
        char *lc_name;
@@ -187,10 +179,6 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
                destroy_op_array(&closure->func.op_array TSRMLS_CC);
        }
 
-       if (closure->this_ptr) {
-               zval_ptr_dtor(&closure->this_ptr);
-       }
-
        efree(closure);
 }
 /* }}} */
@@ -223,17 +211,10 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function
        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;
-               }
-               *ce_ptr = Z_OBJCE_P(closure->this_ptr);
-       } else {
-               if (zobj_ptr) {
-                       *zobj_ptr = NULL;
-               }
-               *ce_ptr = closure->func.common.scope;
+       if (zobj_ptr) {
+               *zobj_ptr = NULL;
        }
+       *ce_ptr = NULL;
        return SUCCESS;
 }
 /* }}} */
@@ -248,13 +229,6 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
        *is_temp = 1;
        ALLOC_HASHTABLE(rv);
        zend_hash_init(rv, 1, NULL, ZVAL_PTR_DTOR, 0);
-       val = closure->this_ptr;
-       if (!val) {
-               ALLOC_INIT_ZVAL(val);
-       } else {
-               Z_ADDREF_P(val);
-       }
-       zend_symtable_update(rv, "this", sizeof("this"), (void *) &val, sizeof(zval *), NULL);
        if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
                HashTable *static_variables = closure->func.op_array.static_variables;
                MAKE_STD_ZVAL(val);
@@ -369,7 +343,7 @@ static int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args,
 }
 /* }}} */
 
-ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zval *this_ptr TSRMLS_DC) /* {{{ */
+ZEND_API void zend_create_closure(zval *res, zend_function *func TSRMLS_DC) /* {{{ */
 {
        zend_closure *closure;
 
@@ -390,19 +364,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
                (*closure->func.op_array.refcount)++;
        }
 
-       closure->func.common.scope = scope;
-       if (scope) {
-               closure->func.common.fn_flags |= ZEND_ACC_PUBLIC;
-               if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
-                       closure->this_ptr = this_ptr;
-                       Z_ADDREF_P(this_ptr);
-               } else {
-                       closure->func.common.fn_flags |= ZEND_ACC_STATIC;
-                       closure->this_ptr = NULL;
-               }
-       } else {
-               closure->this_ptr = NULL;
-       }
+       closure->func.common.scope = NULL;
 }
 /* }}} */
 
index c326e329c4739e2acb10f2d48d0f6008360a6efe..ffbd33f5a705ff16f36155e5c62b6605ea1a9179 100644 (file)
@@ -30,11 +30,9 @@ 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 void zend_create_closure(zval *res, zend_function *op_array TSRMLS_DC);
 ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC);
 ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC);
-ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC);
 
 END_EXTERN_C()
 
index 7f7014b41c586ee6e89775bbaeada48d8e073b2d..8349ed7ca3ee343c5cadf3984ef4b3716ca18f66 100644 (file)
@@ -1389,7 +1389,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
        CG(labels) = NULL;
 }
 
-void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC)
+void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC)
 {
        znode          function_name;
        zend_op_array *current_op_array = CG(active_op_array);
@@ -1409,9 +1409,6 @@ void zend_do_begin_lambda_function_declaration(znode *result, znode *function_to
        zval_dtor(&current_op->op2.u.constant);
        ZVAL_LONG(&current_op->op2.u.constant, zend_hash_func(Z_STRVAL(current_op->op1.u.constant), Z_STRLEN(current_op->op1.u.constant)));
        current_op->result = *result;
-       if (is_static) {
-           CG(active_op_array)->fn_flags |= ZEND_ACC_STATIC;
-       }
        CG(active_op_array)->fn_flags |= ZEND_ACC_CLOSURE;
 }
 
index d9ac44b458817473d67bdaf0a0522560c9463a93..c7b614635b9a08cf92f8a6f11e629ac3a762f4ba 100644 (file)
@@ -434,7 +434,7 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode
 void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
 void zend_do_handle_exception(TSRMLS_D);
 
-void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC);
+void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC);
 void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC);
 
 void zend_do_try(znode *try_token TSRMLS_DC);
index c46f374c06268262364d9654cdcc18bd36430ad3..3e284e93bf640976749c9b2646ac2aab5cfce883 100644 (file)
@@ -647,10 +647,8 @@ expr_without_variable:
        |       T_ARRAY '(' array_pair_list ')' { $$ = $3; }
        |       '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
        |       T_PRINT expr  { zend_do_print(&$$, &$2 TSRMLS_CC); }
-       |       function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
+       |       function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type TSRMLS_CC); }
                        parameter_list ')' lexical_vars '{' inner_statement_list '}' {  zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
-       |       T_STATIC function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); }
-                       parameter_list ')' lexical_vars '{' inner_statement_list '}' {  zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; }
 ;
 
 function:
index 0a849f22cbe65e3bb05069d6b60b0ef9a76a8b2f..8e084ad4731317beb5532faae71a04cd06192b1e 100644 (file)
@@ -4393,7 +4393,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, CONST)
                zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
        }
 
-       zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC);
+       zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array TSRMLS_CC);
 
        ZEND_VM_NEXT_OPCODE();
 }
index d36ee7b03b36188e29028944881369d6f553e520..0bc2f73048a95f0b0a6c1e9a5314447f0c431182 100644 (file)
@@ -2912,7 +2912,7 @@ static int ZEND_FASTCALL  ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_CONST_HANDLER(
                zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
        }
 
-       zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC);
+       zend_create_closure(&EX_T(opline->result.u.var).tmp_var, op_array TSRMLS_CC);
 
        ZEND_VM_NEXT_OPCODE();
 }
index 859b9a93eddba01a30f6b80391a3b02703afde0b..ee137231d2a521c3414792f319be6c35a5052782 100644 (file)
@@ -326,7 +326,7 @@ static zval * reflection_instantiate(zend_class_entry *pce, zval *object TSRMLS_
 }
 
 static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC);
-static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, zval* prop_name, zval* closure, char *indent TSRMLS_DC);
+static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char *indent TSRMLS_DC);
 static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent TSRMLS_DC);
 static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent TSRMLS_DC);
 static void _extension_string(string *str, zend_module_entry *module, char *indent TSRMLS_DC);
@@ -492,7 +492,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
                                        && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce))
                                {
                                        string_printf(str, "\n");
-                                       _function_string(str, mptr, ce, NULL, NULL, sub_indent.string TSRMLS_CC);
+                                       _function_string(str, mptr, ce, sub_indent.string TSRMLS_CC);
                                }
                                zend_hash_move_forward_ex(&ce->function_table, &pos);
                        }
@@ -594,7 +594,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
                                                        closure = NULL;
                                                }
                                                string_printf(&dyn, "\n");
-                                               _function_string(&dyn, mptr, ce, NULL, NULL, sub_indent.string TSRMLS_CC);
+                                               _function_string(&dyn, mptr, ce, sub_indent.string TSRMLS_CC);
                                                count++;
                                                _free_function(closure TSRMLS_CC);
                                        }
@@ -750,8 +750,42 @@ static void _function_parameter_string(string *str, zend_function *fptr, char* i
 }
 /* }}} */
 
+/* {{{ _function_closure_string */
+static void _function_closure_string(string *str, zend_function *fptr, char* indent TSRMLS_DC)
+{
+       zend_uint i, count;
+       ulong num_index;
+       char *key;
+       uint key_len;
+       HashTable *static_variables;
+       HashPosition pos;
+
+       if (fptr->type != ZEND_USER_FUNCTION || !fptr->op_array.static_variables) {
+               return;
+       }
+
+       static_variables = fptr->op_array.static_variables;
+       count = zend_hash_num_elements(static_variables);
+
+       if (!count) {
+               return;
+       }
+
+       string_printf(str, "\n");
+       string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables));
+       zend_hash_internal_pointer_reset_ex(static_variables, &pos);
+       i = 0;
+       while (i < count) {
+               zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
+               string_printf(str, "%s    Variable #%d [ $%s ]\n", indent, i++, key);
+               zend_hash_move_forward_ex(static_variables, &pos);
+       }
+       string_printf(str, "%s}\n", indent);
+}
+/* }}} */
+
 /* {{{ _function_string */
-static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, zval* prop_name, zval* closure, char* indent TSRMLS_DC)
+static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent TSRMLS_DC)
 {
        string param_indent;
        zend_function *overwrites;
@@ -767,7 +801,7 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
        }
 
        string_write(str, indent, strlen(indent));
-       string_printf(str, closure ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
+       string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
        string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
        if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
                string_printf(str, ", deprecated");
@@ -835,7 +869,7 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
        if (fptr->op_array.return_reference) {
                string_printf(str, "&");
        }
-       string_printf(str, "%s ] {\n", closure && prop_name ? Z_STRVAL_P(prop_name) : fptr->common.function_name);
+       string_printf(str, "%s ] {\n", fptr->common.function_name);
        /* The information where a function is declared is only available for user classes */
        if (fptr->type == ZEND_USER_FUNCTION) {
                string_printf(str, "%s  @@ %s %d - %d\n", indent, 
@@ -843,38 +877,11 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
                                                fptr->op_array.line_start,
                                                fptr->op_array.line_end);
        }
-       if (closure) {
-               const zend_function *closure_fptr = zend_get_closure_method_def(closure TSRMLS_CC);
-               zval *closure_this = zend_get_closure_this_ptr(closure TSRMLS_CC);
-               HashTable *static_variables = NULL;
-               int index = 0, count = closure_this ? 1 : 0;
-               if (closure_fptr->type == ZEND_USER_FUNCTION && closure_fptr->op_array.static_variables) {
-                       static_variables = closure_fptr->op_array.static_variables;
-                       count += zend_hash_num_elements(static_variables);
-               }
-               if (count) {
-                       string_printf(str, "\n");
-                       string_printf(str, "%s  - Static Parameters [%d] {\n", indent, count);
-                       if (closure_this) {
-                               string_printf(str, "%s    Parameter #%d [ %s $this ]\n", indent, index++, Z_OBJCE_P(closure_this)->name);
-                       }
-                       if (static_variables) {
-                               HashPosition pos;
-                               uint key_len;
-                               char* key;
-                               ulong num_index;
-                               zend_hash_internal_pointer_reset_ex(static_variables, &pos);
-                               while (index < count) {
-                                       zend_hash_get_current_key_ex(static_variables, &key, &key_len, &num_index, 0, &pos);
-                                       string_printf(str, "%s    Parameter #%d [ $%s ]\n", indent, index++, key);
-                                       zend_hash_move_forward_ex(static_variables, &pos);
-                               }
-                       }
-                       string_printf(str, "%s  }\n", indent);
-               }
-       }
        string_init(&param_indent);
        string_printf(&param_indent, "%s  ", indent);
+       if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) {
+               _function_closure_string(str, fptr, param_indent.string TSRMLS_CC);
+       }
        _function_parameter_string(str, fptr, param_indent.string TSRMLS_CC);
        string_free(&param_indent);
        string_printf(str, "%s}\n", indent);
@@ -1075,7 +1082,7 @@ static void _extension_string(string *str, zend_module_entry *module, char *inde
                                continue;
                        }
                        
-                       _function_string(str, fptr, NULL, NULL, NULL, "    " TSRMLS_CC);
+                       _function_string(str, fptr, NULL, "    " TSRMLS_CC);
                        func++;
                }
                string_printf(str, "%s  }\n", indent);
@@ -1164,12 +1171,15 @@ static void reflection_extension_factory(zval *object, const char *name_str TSRM
 /* }}} */
 
 /* {{{ reflection_parameter_factory */
-static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
+static void reflection_parameter_factory(zend_function *fptr, zval *closure_object, struct _zend_arg_info *arg_info, zend_uint offset, zend_uint required, zval *object TSRMLS_DC)
 {
        reflection_object *intern;
        parameter_reference *reference;
        zval *name;
 
+       if (closure_object) {
+               Z_ADDREF_P(closure_object);
+       }
        MAKE_STD_ZVAL(name);
        if (arg_info->name) {
                ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
@@ -1186,16 +1196,20 @@ static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_i
        intern->ptr = reference;
        intern->ref_type = REF_TYPE_PARAMETER;
        intern->ce = fptr->common.scope;
+       intern->obj = closure_object;
        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
 }
 /* }}} */
 
 /* {{{ reflection_function_factory */
-static void reflection_function_factory(zend_function *function, zval *object TSRMLS_DC)
+static void reflection_function_factory(zend_function *function, zval *closure_object, zval *object TSRMLS_DC)
 {
        reflection_object *intern;
        zval *name;
 
+       if (closure_object) {
+               Z_ADDREF_P(closure_object);
+       }
        MAKE_STD_ZVAL(name);
        ZVAL_STRING(name, function->common.function_name, 1);
 
@@ -1204,17 +1218,21 @@ static void reflection_function_factory(zend_function *function, zval *object TS
        intern->ptr = function;
        intern->ref_type = REF_TYPE_FUNCTION;
        intern->ce = NULL;
+       intern->obj = closure_object;
        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
 }
 /* }}} */
 
 /* {{{ reflection_method_factory */
-static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *object TSRMLS_DC)
+static void reflection_method_factory(zend_class_entry *ce, zend_function *method, zval *closure_object, zval *object TSRMLS_DC)
 {
        reflection_object *intern;
        zval *name;
        zval *classname;
 
+       if (closure_object) {
+               Z_ADDREF_P(closure_object);
+       }
        MAKE_STD_ZVAL(name);
        MAKE_STD_ZVAL(classname);
        ZVAL_STRING(name, method->common.function_name, 1);
@@ -1224,6 +1242,7 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
        intern->ptr = method;
        intern->ref_type = REF_TYPE_FUNCTION;
        intern->ce = ce;
+       intern->obj = closure_object;
        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
        zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
 }
@@ -1522,15 +1541,13 @@ ZEND_METHOD(reflection_function, __toString)
        reflection_object *intern;
        zend_function *fptr;
        string str;
-       zval* name;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        GET_REFLECTION_OBJECT_PTR(fptr);
-       _default_lookup_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
        string_init(&str);
-       _function_string(&str, fptr, intern->ce, name, intern->obj, "" TSRMLS_CC);
+       _function_string(&str, fptr, intern->ce, "" TSRMLS_CC);
        RETURN_STRINGL(str.string, str.len - 1, 0);
 }
 /* }}} */
@@ -1557,28 +1574,7 @@ ZEND_METHOD(reflection_function, isClosure)
                return;
        }
        GET_REFLECTION_OBJECT_PTR(fptr);
-       RETURN_BOOL(intern->obj);
-}
-/* }}} */
-
-/* {{{ proto public bool ReflectionFunction::getClosureThis()
-   Returns this pointer bound to closure */
-ZEND_METHOD(reflection_function, getClosureThis)
-{
-       reflection_object *intern;
-       zend_function *fptr;
-       zval* closure_this;
-
-       if (zend_parse_parameters_none() == FAILURE) {
-               return;
-       }
-       GET_REFLECTION_OBJECT_PTR(fptr);
-       if (intern->obj) {
-               closure_this = zend_get_closure_this_ptr(intern->obj TSRMLS_CC);
-               if (closure_this) {
-                       RETURN_ZVAL(closure_this, 1, 0);
-               }
-       }
+       RETURN_BOOL(fptr->common.fn_flags & ZEND_ACC_CLOSURE);
 }
 /* }}} */
 
@@ -1719,22 +1715,6 @@ ZEND_METHOD(reflection_function, getStaticVariables)
 }
 /* }}} */
 
-/* {{{ proto public mixed ReflectionFunction::getClosure()
-   Returns a dynamically created closure for the function */
-ZEND_METHOD(reflection_function, getClosure)
-{
-       reflection_object *intern;
-       zend_function *fptr;
-       
-       if (zend_parse_parameters_none() == FAILURE) {
-               return;
-       }
-       GET_REFLECTION_OBJECT_PTR(fptr);
-
-       zend_create_closure(return_value, fptr, NULL, NULL TSRMLS_CC);
-}
-/* }}} */
-
 /* {{{ proto public mixed ReflectionFunction::invoke(mixed* args)
    Invokes the function */
 ZEND_METHOD(reflection_function, invoke)
@@ -1912,7 +1892,7 @@ ZEND_METHOD(reflection_function, getParameters)
                zval *parameter;   
 
                ALLOC_ZVAL(parameter);
-               reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
+               reflection_parameter_factory(_copy_function(fptr TSRMLS_CC), intern->obj, arg_info, i, fptr->common.required_num_args, parameter TSRMLS_CC);
                add_next_index_zval(return_value, parameter);
 
                arg_info++;
@@ -1989,6 +1969,7 @@ ZEND_METHOD(reflection_parameter, __construct)
        struct _zend_arg_info *arg_info;
        int position;
        zend_class_entry *ce = NULL;
+       zend_bool is_closure = 0;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zZ", &reference, &parameter) == FAILURE) {
                return;
@@ -2053,7 +2034,8 @@ ZEND_METHOD(reflection_parameter, __construct)
                                        && memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                                        && (fptr = zend_get_closure_invoke_method(*classref TSRMLS_CC)) != NULL)
                                {
-                                       /* nothign to do */
+                                       /* nothign to do. don't set is_closure since is the invoke handler,
+                                          not the closure itself */
                                } else if (zend_hash_find(&ce->function_table, lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
                                        efree(lcname);
                                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
@@ -2068,7 +2050,9 @@ ZEND_METHOD(reflection_parameter, __construct)
                                ce = Z_OBJCE_P(reference);
                                
                                if (instanceof_function(ce, zend_ce_closure TSRMLS_CC)) {
-                                       fptr = zend_get_closure_invoke_method(reference TSRMLS_CC);
+                                       fptr = (zend_function *)zend_get_closure_method_def(reference TSRMLS_CC);
+                                       Z_ADDREF_P(reference);
+                                       is_closure = 1;
                                } else if (zend_hash_find(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME), (void **)&fptr) == FAILURE) {
                                        zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
                                                "Method %s::%s() does not exist", ce->name, ZEND_INVOKE_FUNC_NAME);
@@ -2132,10 +2116,13 @@ ZEND_METHOD(reflection_parameter, __construct)
        ref->offset = (zend_uint)position;
        ref->required = fptr->common.required_num_args;
        ref->fptr = fptr;
-       // TODO: copy fptr
+       /* TODO: copy fptr */
        intern->ptr = ref;
        intern->ref_type = REF_TYPE_PARAMETER;
        intern->ce = ce;
+       if (reference && is_closure) {
+               intern->obj = reference;
+       }
 }
 /* }}} */
 
@@ -2181,9 +2168,9 @@ ZEND_METHOD(reflection_parameter, getDeclaringFunction)
        GET_REFLECTION_OBJECT_PTR(param);
 
        if (!param->fptr->common.scope) {
-               reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
+               reflection_function_factory(_copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
        } else {
-               reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), return_value TSRMLS_CC);
+               reflection_method_factory(param->fptr->common.scope, _copy_function(param->fptr TSRMLS_CC), intern->obj, return_value TSRMLS_CC);
        }
 }
 /* }}} */
@@ -2431,11 +2418,7 @@ ZEND_METHOD(reflection_method, __construct)
        int name_len, tmp_len;
        zval ztmp;
 
-       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "o", &classname) == SUCCESS) {
-               name_str = ZEND_INVOKE_FUNC_NAME;
-               name_len = sizeof(ZEND_INVOKE_FUNC_NAME)-1;
-               orig_obj = classname;
-       } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
+       if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
                        return;
                }
@@ -2504,45 +2487,15 @@ ZEND_METHOD(reflection_method, __construct)
        {
                /* do nothing, mptr already set */
        } else if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
-               /* Check if this is a property storing a closure */
-               mptr = NULL;  /* Set by closure detection again */
-               if (orig_obj) {
-                       zval **callable, member;
-                       zend_property_info *property_info;
-                       zend_object *zobj = zend_objects_get_address(orig_obj TSRMLS_CC);
-
-                       ZVAL_STRINGL(&member, name_str, name_len, 0);
-                       property_info = zend_get_property_info(ce, &member, 1 TSRMLS_CC);
-       
-                       if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &callable) == SUCCESS) {
-                               zval *callable_obj;
-                               zend_class_entry *ce_ptr;
-                               zend_function *fbc;
-       
-                               if (Z_TYPE_PP(callable) == IS_OBJECT
-                               && Z_OBJ_HANDLER_PP(callable, get_closure)
-                               && Z_OBJ_HANDLER_PP(callable, get_closure)(*callable, &ce_ptr, &fbc, &callable_obj TSRMLS_CC) == SUCCESS) {
-                                       mptr = fbc;
-                                       Z_ADDREF_PP(callable);
-                                       intern->obj = *callable;
-                               }
-                       }
-               }
-               if (!mptr) {
-                       efree(lcname);
-                       zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
-                               "Method %s::%s() does not exist", ce->name, name_str);
-                       return;
-               }
+               efree(lcname);
+               zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, 
+                       "Method %s::%s() does not exist", ce->name, name_str);
+               return;
        }
        efree(lcname);
 
        MAKE_STD_ZVAL(name);
-       if (intern->obj) {
-               ZVAL_STRINGL(name, name_str, name_len, 1);
-       } else {
-               ZVAL_STRING(name, mptr->common.function_name, 1);
-       }
+       ZVAL_STRING(name, mptr->common.function_name, 1);
        zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
        intern->ptr = mptr;
        intern->ref_type = REF_TYPE_FUNCTION;
@@ -2557,54 +2510,17 @@ ZEND_METHOD(reflection_method, __toString)
        reflection_object *intern;
        zend_function *mptr;
        string str;
-       zval *name;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        GET_REFLECTION_OBJECT_PTR(mptr);
-       _default_lookup_entry(getThis(), "name", sizeof("name"), &name TSRMLS_CC);
        string_init(&str);
-       _function_string(&str, mptr, intern->ce, name, intern->obj, "" TSRMLS_CC);
+       _function_string(&str, mptr, intern->ce, "" TSRMLS_CC);
        RETURN_STRINGL(str.string, str.len - 1, 0);
 }
 /* }}} */
 
-/* {{{ proto public mixed ReflectionMethod::getClosure([mixed object])
-   Invokes the function */
-ZEND_METHOD(reflection_method, getClosure)
-{
-       reflection_object *intern;
-       zval *obj;
-       zend_function *mptr;
-       
-       METHOD_NOTSTATIC(reflection_method_ptr);
-       GET_REFLECTION_OBJECT_PTR(mptr);
-
-       if (mptr->common.fn_flags & ZEND_ACC_STATIC)  {
-               zend_create_closure(return_value, mptr, mptr->common.scope, NULL TSRMLS_CC);
-       } else {
-               if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
-                       return;
-               }
-
-               if (!instanceof_function(Z_OBJCE_P(obj), mptr->common.scope TSRMLS_CC)) {
-                       _DO_THROW("Given object is not an instance of the class this method was declared in");
-                       /* Returns from this function */
-               }
-
-               /* This is an original closure object and __invoke is to be called. */
-               if (Z_OBJCE_P(obj) == zend_ce_closure && mptr->type == ZEND_INTERNAL_FUNCTION &&
-                       (mptr->internal_function.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0)
-               {
-                       RETURN_ZVAL(obj, 1, 0);
-               } else {
-                       zend_create_closure(return_value, mptr, mptr->common.scope, obj TSRMLS_CC);
-               }
-       }
-}
-/* }}} */
-
 /* {{{ proto public mixed ReflectionMethod::invoke(mixed object, mixed* args)
    Invokes the method. */
 ZEND_METHOD(reflection_method, invoke)
@@ -3017,7 +2933,7 @@ ZEND_METHOD(reflection_method, getPrototype)
                return;
        }
 
-       reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, return_value TSRMLS_CC);
+       reflection_method_factory(mptr->common.prototype->common.scope, mptr->common.prototype, NULL, return_value TSRMLS_CC);
 }
 /* }}} */
 
@@ -3397,7 +3313,7 @@ ZEND_METHOD(reflection_class, getConstructor)
        GET_REFLECTION_OBJECT_PTR(ce);
 
        if (ce->constructor) {
-               reflection_method_factory(ce, ce->constructor, return_value TSRMLS_CC);
+               reflection_method_factory(ce, ce->constructor, NULL, return_value TSRMLS_CC);
        } else {
                RETURN_NULL();
        }
@@ -3451,10 +3367,12 @@ ZEND_METHOD(reflection_class, getMethod)
                && memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
                && (mptr = zend_get_closure_invoke_method(intern->obj TSRMLS_CC)) != NULL)
        {
-               reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
+               /* don't assign closure_object since we only reflect the invoke handler
+                  method and not the closure definition itself */
+               reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
                efree(lc_name);
        } else if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
-               reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
+               reflection_method_factory(ce, mptr, NULL, return_value TSRMLS_CC);
                efree(lc_name);
        } else {
                efree(lc_name);
@@ -3480,7 +3398,10 @@ static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval,
                {
                        mptr = closure;
                }
-               reflection_method_factory(ce, mptr, method TSRMLS_CC);
+               /* don't assign closure_object since we only reflect the invoke handler
+                  method and not the closure definition itself, even if we have a
+                  closure */
+               reflection_method_factory(ce, mptr, NULL, method TSRMLS_CC);
                add_next_index_zval(retval, method);
        }
 }
@@ -4839,7 +4760,7 @@ ZEND_METHOD(reflection_extension, getFunctions)
                        }
                        
                        ALLOC_ZVAL(function);
-                       reflection_function_factory(fptr, function TSRMLS_CC);
+                       reflection_function_factory(fptr, NULL, function TSRMLS_CC);
                        add_assoc_zval_ex(return_value, func->fname, strlen(func->fname)+1, function);
                        func++;
                }
@@ -5090,7 +5011,6 @@ static const zend_function_entry reflection_function_abstract_functions[] = {
        ZEND_ME(reflection_function, isDeprecated, NULL, 0)
        ZEND_ME(reflection_function, isInternal, NULL, 0)
        ZEND_ME(reflection_function, isUserDefined, NULL, 0)
-       ZEND_ME(reflection_function, getClosureThis, NULL, 0)
        ZEND_ME(reflection_function, getDocComment, NULL, 0)
        ZEND_ME(reflection_function, getEndLine, NULL, 0)
        ZEND_ME(reflection_function, getExtension, NULL, 0)
@@ -5113,7 +5033,6 @@ static const zend_function_entry reflection_function_functions[] = {
        ZEND_ME(reflection_function, __toString, NULL, 0)
        ZEND_ME(reflection_function, export, arginfo_reflection_function_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC)
        ZEND_ME(reflection_function, isDisabled, NULL, 0)
-       ZEND_ME(reflection_function, getClosure, NULL, 0)
        ZEND_ME(reflection_function, invoke, arginfo_reflection_function_invoke, 0)
        ZEND_ME(reflection_function, invokeArgs, arginfo_reflection_function_invokeArgs, 0)
        {NULL, NULL, NULL}
@@ -5153,7 +5072,6 @@ static const zend_function_entry reflection_method_functions[] = {
        ZEND_ME(reflection_method, isConstructor, NULL, 0)
        ZEND_ME(reflection_method, isDestructor, NULL, 0)
        ZEND_ME(reflection_method, getModifiers, NULL, 0)
-       ZEND_ME(reflection_method, getClosure, NULL, 0)
        ZEND_ME(reflection_method, invoke, arginfo_reflection_method_invoke, 0)
        ZEND_ME(reflection_method, invokeArgs, arginfo_reflection_method_invokeArgs, 0)
        ZEND_ME(reflection_method, getDeclaringClass, NULL, 0)
diff --git a/ext/reflection/tests/027.phpt b/ext/reflection/tests/027.phpt
deleted file mode 100755 (executable)
index a2bda4f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
---TEST--
---FILE--
-<?php
-
-$global = 42;
-
-$func = function($x, stdClass $y=NULL) use($global) {
-       static $static;
-};
-
-ReflectionFunction::Export($func);
-
-$r = new ReflectionFunction($func);
-
-var_dump(@get_class($r->getClosureThis()));
-var_dump($r->getName());
-var_dump($r->isClosure());
-
-Class Test {
-       public $func;
-       function __construct(){
-               global $global;
-               $this->func = function($x, stdClass $y = NULL) use($global) {
-                       static $static;
-               };
-       }
-}
-
-ReflectionMethod::export(new Test, "func");
-
-$r = new ReflectionMethod(new Test, "func");
-
-var_dump(get_class($r->getClosureThis()));
-var_dump($r->getName());
-var_dump($r->isClosure());
-
-?>
-===DONE===
---EXPECTF--
-Closure [ <user> function {closure} ] {
-  @@ %s027.php 5 - 7
-
-  - Static Parameters [2] {
-    Parameter #0 [ $global ]
-    Parameter #1 [ $static ]
-  }
-
-  - Parameters [2] {
-    Parameter #0 [ <required> $x ]
-    Parameter #1 [ <optional> stdClass or NULL $y = NULL ]
-  }
-}
-
-NULL
-string(9) "{closure}"
-bool(true)
-Closure [ <user> public method func ] {
-  @@ %s027.php 21 - 23
-
-  - Static Parameters [3] {
-    Parameter #0 [ Test $this ]
-    Parameter #1 [ $global ]
-    Parameter #2 [ $static ]
-  }
-
-  - Parameters [2] {
-    Parameter #0 [ <required> $x ]
-    Parameter #1 [ <optional> stdClass or NULL $y = NULL ]
-  }
-}
-
-string(4) "Test"
-string(4) "func"
-bool(true)
-===DONE===
diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_basic.phpt
deleted file mode 100644 (file)
index 832d31c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
---TEST--
-Test ReflectionFunction::getClosure() function : basic functionality 
---FILE--
-<?php
-/* Prototype  : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the function 
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions: 
- */
-
-echo "*** Testing ReflectionFunction::getClosure() : basic functionality ***\n";
-
-function foo()
-{
-       var_dump( "Inside foo function" );
-}
-
-function bar( $arg )
-{
-       var_dump( "Arg is " . $arg );
-}
-
-$func = new ReflectionFunction( 'foo' );
-$closure = $func->getClosure();
-$closure();
-
-$func = new ReflectionFunction( 'bar' );
-$closure = $func->getClosure();
-$closure( 'succeeded' );
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionFunction::getClosure() : basic functionality ***
-%unicode|string%(19) "Inside foo function"
-%unicode|string%(16) "Arg is succeeded"
-===DONE===
diff --git a/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt b/ext/reflection/tests/ReflectionFunction_getClosure_error.phpt
deleted file mode 100644 (file)
index 9a963e4..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
---TEST--
-Test ReflectionFunction::getClosure() function : error functionality
---FILE--
-<?php
-/* Prototype  : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the function
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions:
- */
-
-echo "*** Testing ReflectionFunction::getClosure() : error conditions ***\n";
-
-function foo()
-{
-       var_dump( "Inside foo function" );
-}
-
-$func = new ReflectionFunction( 'foo' );
-$closure = $func->getClosure('bar');
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionFunction::getClosure() : error conditions ***
-
-Warning: ReflectionFunction::getClosure() expects exactly 0 parameters, 1 given in %s on line %d
-===DONE===
diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_basic.phpt
deleted file mode 100644 (file)
index d8bdbe1..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
---TEST--
-Test ReflectionMethod::getClosure() function : basic functionality 
---FILE--
-<?php
-/* Prototype  : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the method 
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions: 
- */
-
-echo "*** Testing ReflectionMethod::getClosure() : basic functionality ***\n";
-
-class StaticExample
-{
-       static function foo()
-       {
-               var_dump( "Static Example class, Hello World!" );
-       }
-}
-
-class Example
-{
-       public $bar = 42;
-       public function foo()
-       {
-               var_dump( "Example class, bar: " . $this->bar );
-       }
-}
-
-// Initialize classes
-$class = new ReflectionClass( 'Example' );
-$staticclass = new ReflectionClass( 'StaticExample' );
-$object = new Example();
-$fakeobj = new StdClass();
-
-
-$method = $staticclass->getMethod( 'foo' );
-$closure = $method->getClosure();
-$closure();
-
-$method = $class->getMethod( 'foo' );
-
-$closure = $method->getClosure( $object );
-$closure();
-$object->bar = 34;
-$closure();
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionMethod::getClosure() : basic functionality ***
-%unicode|string%(34) "Static Example class, Hello World!"
-%unicode|string%(22) "Example class, bar: 42"
-%unicode|string%(22) "Example class, bar: 34"
-===DONE===
diff --git a/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt b/ext/reflection/tests/ReflectionMethod_getClosure_error.phpt
deleted file mode 100644 (file)
index 6f1e91e..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
---TEST--
-Test ReflectionMethod::getClosure() function : error functionality
---FILE--
-<?php
-/* Prototype  : public mixed ReflectionFunction::getClosure()
- * Description: Returns a dynamically created closure for the method
- * Source code: ext/reflection/php_reflection.c
- * Alias to functions:
- */
-
-echo "*** Testing ReflectionMethod::getClosure() : error conditions ***\n";
-
-class StaticExample
-{
-       static function foo()
-       {
-               var_dump( "Static Example class, Hello World!" );
-       }
-}
-
-class Example
-{
-       public $bar = 42;
-       public function foo()
-       {
-               var_dump( "Example class, bar: " . $this->bar );
-       }
-}
-
-// Initialize classes
-$class = new ReflectionClass( 'Example' );
-$staticclass = new ReflectionClass( 'StaticExample' );
-$method = $class->getMethod( 'foo' );
-$staticmethod = $staticclass->getMethod( 'foo' );
-$object = new Example();
-$fakeobj = new StdClass();
-
-echo "\n-- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --\n";
-var_dump( $staticmethod->getClosure( 'foobar' ) );
-var_dump( $staticmethod->getClosure( 'foo', 'bar' ) );
-var_dump( $method->getClosure( $object, 'foobar' ) );
-
-echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n";
-$closure = $method->getClosure();
-
-echo "\n-- Testing ReflectionMethod::getClosure() function with Zero arguments --\n";
-try {
-        var_dump( $method->getClosure( $fakeobj ) );
-} catch( Exception $e ) {
-        var_dump( $e->getMessage() );
-}
-
-?>
-===DONE===
---EXPECTF--
-*** Testing ReflectionMethod::getClosure() : error conditions ***
-
--- Testing ReflectionMethod::getClosure() function with more than expected no. of arguments --
-object(Closure)#%d (1) {
-  ["this"]=>
-  NULL
-}
-object(Closure)#%d (1) {
-  ["this"]=>
-  NULL
-}
-
-Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 2 given in %s on line %d
-NULL
-
--- Testing ReflectionMethod::getClosure() function with Zero arguments --
-
-Warning: ReflectionMethod::getClosure() expects exactly 1 parameter, 0 given in %s on line %d
-
--- Testing ReflectionMethod::getClosure() function with Zero arguments --
-%unicode|string%(72) "Given object is not an instance of the class this method was declared in"
-===DONE===
index cd8815c2b73bf6e5e1916a409e1244c43fe984ba..6cc7e6755cdc8c9e81f2b554ed010683218e2693 100755 (executable)
@@ -19,7 +19,7 @@ foreach($rms as $rm) {
 
 echo "---\n";
 
-$rm = new ReflectionMethod($closure);
+$rm = new ReflectionMethod($closure, '__invoke');
 var_dump($rm->getName());
 var_dump($rm->getNumberOfParameters());
 var_dump($rm->getNumberOfRequiredParameters());
index d6660de74bc26cd01210a8f23995bacb6260f1d8..e8b080f5cbbbbc4a44246952b9bc76d0599a0a2e 100755 (executable)
@@ -7,15 +7,15 @@ class Test {
        function __invoke($a, $b = 0) { }
 }
 
-$rm = new ReflectionMethod(new Test);
+$rm = new ReflectionMethod(new Test, '__invoke');
 var_dump($rm->getName());
 var_dump($rm->getNumberOfParameters());
 var_dump($rm->getNumberOfRequiredParameters());
 
-$rp = new ReflectionParameter(new Test, 0);
+$rp = new ReflectionParameter(array(new Test, '__invoke'), 0);
 var_dump($rp->isOptional());
 
-$rp = new ReflectionParameter(new Test, 1);
+$rp = new ReflectionParameter(array(new Test, '__invoke'), 1);
 var_dump($rp->isOptional());
 
 ?>
index cc309397b560ff53d4686741d12ac51e9c2d210c..4483dc06e3c102929a8523e5c3db74fe3f8e838a 100644 (file)
@@ -5,14 +5,14 @@ Reflection on closures: Segfaults with getParameters() and getDeclaringFunction(
 
 $closure = function($a, $b = 0) { };
 
-$method = new ReflectionMethod ($closure);
+$method = new ReflectionMethod ($closure, '__invoke');
 $params = $method->getParameters ();
 unset ($method);
 $method = $params[0]->getDeclaringFunction ();
 unset ($params);
 echo $method->getName ()."\n";
 
-$parameter = new ReflectionParameter ($closure, 'b');
+$parameter = new ReflectionParameter (array ($closure, '__invoke'), 'b');
 $method = $parameter->getDeclaringFunction ();
 unset ($parameter);
 echo $method->getName ()."\n";
diff --git a/ext/reflection/tests/closures_004.phpt b/ext/reflection/tests/closures_004.phpt
deleted file mode 100644 (file)
index 6b75045..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
---TEST--
-Reflection on closures: Segfault with getClosure() on closure itself
---FILE-- 
-<?php
-
-$closure = function() { echo "Invoked!\n"; };
-
-$method = new ReflectionMethod ($closure);
-
-$closure2 = $method->getClosure ($closure);
-
-$closure2 ();
-$closure2->__invoke ();
-
-unset ($closure);
-
-$closure2 ();
-$closure2->__invoke ();
-
-?>
-===DONE===
---EXPECTF--
-Invoked!
-Invoked!
-Invoked!
-Invoked!
-===DONE===