summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-07-05 15:43:27 +0200
committerNikita Popov <nikic@php.net>2016-07-05 15:44:17 +0200
commitceae9fb54013d1fac0bf7987398501915b054209 (patch)
tree5c002d22e4407794b8060e099b2ff135af30f6b6
parente959a9b65234902acb4e25602ac05d4cd546f8a7 (diff)
downloadphp-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.phpt17
-rw-r--r--Zend/zend_closures.c12
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;