diff options
author | Nikita Popov <nikic@php.net> | 2016-07-05 15:43:27 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2016-07-05 15:44:17 +0200 |
commit | ceae9fb54013d1fac0bf7987398501915b054209 (patch) | |
tree | 5c002d22e4407794b8060e099b2ff135af30f6b6 | |
parent | e959a9b65234902acb4e25602ac05d4cd546f8a7 (diff) | |
download | php-git-ceae9fb54013d1fac0bf7987398501915b054209.tar.gz |
Closure::fromCallable(): Better LSB handling
The previous fix missed the "late" part of "late static binding" :)
-rw-r--r-- | Zend/tests/closures/closure_from_callable_lsb.phpt | 17 | ||||
-rw-r--r-- | Zend/zend_closures.c | 12 |
2 files changed, 15 insertions, 14 deletions
diff --git a/Zend/tests/closures/closure_from_callable_lsb.phpt b/Zend/tests/closures/closure_from_callable_lsb.phpt index bd57fba72e..950985bdad 100644 --- a/Zend/tests/closures/closure_from_callable_lsb.phpt +++ b/Zend/tests/closures/closure_from_callable_lsb.phpt @@ -3,14 +3,19 @@ Testing Closure::fromCallable() functionality: Late static binding --FILE-- <?php -class Foo { - const BAR = 1; - public static function method() { - return static::BAR; +class A { + public static function test() { + var_dump(static::class); } } -var_dump(Closure::fromCallable(['Foo', 'method'])()); + +class B extends A { +} + +Closure::fromCallable(['A', 'test'])(); +Closure::fromCallable(['B', 'test'])(); ?> --EXPECT-- -int(1) +string(1) "A" +string(1) "B" diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index ef321e7cbf..137e437fb9 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -238,6 +238,7 @@ ZEND_METHOD(Closure, bind) static void zend_closure_call_magic(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { zend_fcall_info fci; zend_fcall_info_cache fcc; + zval params[2]; memset(&fci, 0, sizeof(zend_fcall_info)); memset(&fci, 0, sizeof(zend_fcall_info_cache)); @@ -247,7 +248,7 @@ static void zend_closure_call_magic(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { fcc.initialized = 1; fcc.function_handler = (zend_function *) EX(func)->common.arg_info; - fci.params = (zval*) emalloc(sizeof(zval) * 2); + fci.params = params; fci.param_count = 2; ZVAL_STR(&fci.params[0], EX(func)->common.function_name); array_init(&fci.params[1]); @@ -261,7 +262,6 @@ static void zend_closure_call_magic(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ { zval_ptr_dtor(&fci.params[0]); zval_ptr_dtor(&fci.params[1]); - efree(fci.params); } /* }}} */ @@ -276,10 +276,6 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, } mptr = fcc.function_handler; - if (mptr == NULL) { - return FAILURE; - } - if (mptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { memset(&call, 0, sizeof(zend_internal_function)); @@ -295,9 +291,9 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, if (fcc.object) { ZVAL_OBJ(&instance, fcc.object); - zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.object->ce, &instance); + zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.called_scope, &instance); } else { - zend_create_fake_closure(return_value, mptr, mptr->common.scope, mptr->common.scope, NULL); + zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.called_scope, NULL); } return SUCCESS; |