diff options
author | Dmitry Stogov <dmitry@zend.com> | 2018-10-01 11:19:36 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2018-10-01 11:19:36 +0300 |
commit | 2d87b51ae9dafc4000830bdebd49d7665d0a4f6f (patch) | |
tree | 2610a5e2641e17ba8bdbcebc618a73c6dfcb8e13 /Zend/zend_generators.c | |
parent | 9d47cb4593972859d7bb8747f1f0b8ae56d7712e (diff) | |
parent | 4fc5833b3ebda3078911808d296e62d5baa9bf52 (diff) | |
download | php-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.c | 36 |
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) { |