summaryrefslogtreecommitdiff
path: root/Zend/zend_generators.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-10-01 11:19:36 +0300
committerDmitry Stogov <dmitry@zend.com>2018-10-01 11:19:36 +0300
commit2d87b51ae9dafc4000830bdebd49d7665d0a4f6f (patch)
tree2610a5e2641e17ba8bdbcebc618a73c6dfcb8e13 /Zend/zend_generators.c
parent9d47cb4593972859d7bb8747f1f0b8ae56d7712e (diff)
parent4fc5833b3ebda3078911808d296e62d5baa9bf52 (diff)
downloadphp-git-2d87b51ae9dafc4000830bdebd49d7665d0a4f6f.tar.gz
Merge branch 'master' of git.php.net:php-src
* 'master' of git.php.net:php-src: (29 commits) Fix the deplister rule to not ignore the .c file (Anatol) Update .gitignore to include the Windows deplister program (win32/build/deplister.c) Bug > Feature Request NEWS and UPGRADING Fixed bug #75479 Fix test Fix some tests and improve coverage for Windows in SPL Use already set variable Fix reflection arguments for sodium_memzero function Deprecate unbinding of $this of non-static methods Generalize compile_typename Fixed bug #76737 Fixed bug #72635 Remove and refactor ext/spl/examples Remove outdated soap examples Remove unused ext/bz2/php_bz2.def Remove redundant ce from reflection property_reference Only store zend_type inside reflection type_reference Fixed bug #76946 Bump versions for 7.1.24-dev ...
Diffstat (limited to 'Zend/zend_generators.c')
-rw-r--r--Zend/zend_generators.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 0198b3171e..1162c7653f 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -276,6 +276,25 @@ static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */
size += Z_TYPE(execute_data->This) == IS_OBJECT; /* $this */
size += (EX_CALL_INFO() & ZEND_CALL_CLOSURE) != 0; /* Closure object */
+ /* Live vars */
+ if (execute_data->opline != op_array->opcodes) {
+ /* -1 required because we want the last run opcode, not the next to-be-run one. */
+ uint32_t i, op_num = execute_data->opline - op_array->opcodes - 1;
+ for (i = 0; i < op_array->last_live_range; i++) {
+ const zend_live_range *range = &op_array->live_range[i];
+ if (range->start > op_num) {
+ /* Further ranges will not be relevant... */
+ break;
+ } else if (op_num < range->end) {
+ /* LIVE_ROPE and LIVE_SILENCE not relevant for GC */
+ uint32_t kind = range->var & ZEND_LIVE_MASK;
+ if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) {
+ size++;
+ }
+ }
+ }
+ }
+
/* Yield from root references */
if (generator->node.children == 0) {
zend_generator *root = generator->node.ptr.root;
@@ -342,6 +361,23 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {
ZVAL_OBJ(gc_buffer++, ZEND_CLOSURE_OBJECT(EX(func)));
}
+ if (execute_data->opline != op_array->opcodes) {
+ uint32_t i, op_num = execute_data->opline - op_array->opcodes - 1;
+ for (i = 0; i < op_array->last_live_range; i++) {
+ const zend_live_range *range = &op_array->live_range[i];
+ if (range->start > op_num) {
+ break;
+ } else if (op_num < range->end) {
+ uint32_t kind = range->var & ZEND_LIVE_MASK;
+ uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
+ zval *var = EX_VAR(var_num);
+ if (kind == ZEND_LIVE_TMPVAR || kind == ZEND_LIVE_LOOP) {
+ ZVAL_COPY_VALUE(gc_buffer++, var);
+ }
+ }
+ }
+ }
+
if (generator->node.children == 0) {
zend_generator *root = generator->node.ptr.root;
while (root != generator) {