]> granicus.if.org Git - php/commitdiff
Fixed memory leak
authorDmitry Stogov <dmitry@zend.com>
Thu, 14 May 2015 14:07:32 +0000 (17:07 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 14 May 2015 14:07:32 +0000 (17:07 +0300)
Zend/tests/generators/generator_closure_unused.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/generator_closure_unused.phpt b/Zend/tests/generators/generator_closure_unused.phpt
new file mode 100644 (file)
index 0000000..9acf8f9
--- /dev/null
@@ -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
index facc1f8696109082153cc473bbd2543305bab62e..c1f855809c206fab99da4245dc09ecbb27395c3a 100644 (file)
@@ -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 {
index d4902ef9729862ecd8bc0035fd743d1ff01548e2..6b7f91b8d7b3f7fbe27f2002be3d9b55c4e1cd23 100644 (file)
@@ -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 {