summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-05-14 17:07:32 +0300
committerDmitry Stogov <dmitry@zend.com>2015-05-14 17:07:32 +0300
commitfc75d07652717a374e01aa557b165af3fc9606b6 (patch)
treeb34f02e7da0442399f327b39c9768d78e9997659
parent0604df8a82084f2b7d4a46baf28edefa764c1dd2 (diff)
downloadphp-git-fc75d07652717a374e01aa557b165af3fc9606b6.tar.gz
Fixed memory leak
-rw-r--r--Zend/tests/generators/generator_closure_unused.phpt9
-rw-r--r--Zend/zend_vm_def.h7
-rw-r--r--Zend/zend_vm_execute.h7
3 files changed, 19 insertions, 4 deletions
diff --git a/Zend/tests/generators/generator_closure_unused.phpt b/Zend/tests/generators/generator_closure_unused.phpt
new file mode 100644
index 0000000000..9acf8f9d93
--- /dev/null
+++ b/Zend/tests/generators/generator_closure_unused.phpt
@@ -0,0 +1,9 @@
+--TEST--
+Closures can be unused generators
+--FILE--
+<?php
+(function(){yield;})();
+echo "ok\n";
+?>
+--EXPECT--
+ok \ No newline at end of file
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index facc1f8696..c1f855809c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -3563,7 +3563,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
EG(scope) = NULL;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
- if (RETURN_VALUE_USED(opline)) {
+ if (EXPECTED(RETURN_VALUE_USED(opline))) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
Z_VAR_FLAGS_P(ret) = 0;
@@ -3685,11 +3685,14 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
EG(scope) = fbc->common.scope;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
- if (RETURN_VALUE_USED(opline)) {
+ if (EXPECTED(RETURN_VALUE_USED(opline))) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
Z_VAR_FLAGS_P(ret) = 0;
} else {
+ if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
+ OBJ_RELEASE((zend_object*)fbc->op_array.prototype);
+ }
zend_vm_stack_free_args(call);
}
} else {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d4902ef972..6b7f91b8d7 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -627,7 +627,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
EG(scope) = NULL;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
- if (RETURN_VALUE_USED(opline)) {
+ if (EXPECTED(RETURN_VALUE_USED(opline))) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
Z_VAR_FLAGS_P(ret) = 0;
@@ -749,11 +749,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
EG(scope) = fbc->common.scope;
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
- if (RETURN_VALUE_USED(opline)) {
+ if (EXPECTED(RETURN_VALUE_USED(opline))) {
ret = EX_VAR(opline->result.var);
zend_generator_create_zval(call, &fbc->op_array, ret);
Z_VAR_FLAGS_P(ret) = 0;
} else {
+ if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
+ OBJ_RELEASE((zend_object*)fbc->op_array.prototype);
+ }
zend_vm_stack_free_args(call);
}
} else {