From 9a159f37e14802c9d38df305f125446be34f98f6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 9 Jan 2017 22:24:21 +0300 Subject: [PATCH] Improved GENERATOR_CREATE opcode handler. --- NEWS | 1 + Zend/zend_vm_def.h | 10 ++++++++-- Zend/zend_vm_execute.h | 10 ++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 082f7836f4..bd7cabc225 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ PHP NEWS ?? ??? 2017, PHP 7.1.2 - Core: + . Improved GENERATOR_CREATE opcode handler. (Bob, Dmitry) . Fixed bug #73877 (readlink() returns garbage for UTF-8 paths). (Anatol) . Fixed bug #73876 (Crash when exporting **= in expansion of assign op). (Sara) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8987e6bcf7..80b06ff25a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4093,8 +4093,14 @@ ZEND_VM_HANDLER(41, ZEND_GENERATOR_CREATE, ANY, ANY) * is allocated on heap. */ num_args = EX_NUM_ARGS(); - used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - MIN(EX(func)->op_array.num_args, num_args)) * sizeof(zval); - gen_execute_data = (zend_execute_data*)emalloc(used_stack); + if (EXPECTED(num_args <= EX(func)->op_array.last_var)) { + used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var + EX(func)->op_array.T) * sizeof(zval); + gen_execute_data = (zend_execute_data*)emalloc(used_stack); + used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var) * sizeof(zval); + } else { + used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - EX(func)->op_array.num_args) * sizeof(zval); + gen_execute_data = (zend_execute_data*)emalloc(used_stack); + } memcpy(gen_execute_data, execute_data, used_stack); /* Save execution context in generator object. */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 972594df00..04f33ca12c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1179,8 +1179,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER( * is allocated on heap. */ num_args = EX_NUM_ARGS(); - used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - MIN(EX(func)->op_array.num_args, num_args)) * sizeof(zval); - gen_execute_data = (zend_execute_data*)emalloc(used_stack); + if (EXPECTED(num_args <= EX(func)->op_array.last_var)) { + used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var + EX(func)->op_array.T) * sizeof(zval); + gen_execute_data = (zend_execute_data*)emalloc(used_stack); + used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var) * sizeof(zval); + } else { + used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - EX(func)->op_array.num_args) * sizeof(zval); + gen_execute_data = (zend_execute_data*)emalloc(used_stack); + } memcpy(gen_execute_data, execute_data, used_stack); /* Save execution context in generator object. */ -- 2.40.0