diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-05-14 17:07:32 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-05-14 17:07:32 +0300 |
commit | fc75d07652717a374e01aa557b165af3fc9606b6 (patch) | |
tree | b34f02e7da0442399f327b39c9768d78e9997659 | |
parent | 0604df8a82084f2b7d4a46baf28edefa764c1dd2 (diff) | |
download | php-git-fc75d07652717a374e01aa557b165af3fc9606b6.tar.gz |
Fixed memory leak
-rw-r--r-- | Zend/tests/generators/generator_closure_unused.phpt | 9 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 7 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 7 |
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 { |