diff options
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r-- | Zend/zend_execute.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 354b3f3eba..5396334091 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3188,6 +3188,49 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva } /* }}} */ +static zend_never_inline zend_bool ZEND_FASTCALL zend_fe_reset_iterator(zval *array_ptr, int by_ref OPLINE_DC) /* {{{ */ +{ + zend_class_entry *ce = Z_OBJCE_P(array_ptr); + zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, by_ref); + zend_bool is_empty; + + if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { + if (iter) { + OBJ_RELEASE(&iter->std); + } + if (!EG(exception)) { + zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + return 1; + } + + iter->index = 0; + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(&iter->std); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + return 1; + } + } + + is_empty = iter->funcs->valid(iter) != SUCCESS; + + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(&iter->std); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + return 1; + } + iter->index = -1; /* will be set to 0 before using next handler */ + + ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + + return is_empty; +} +/* }}} */ + #ifdef ZEND_VM_TRACE_HANDLERS # include "zend_vm_trace_handlers.h" #elif defined(ZEND_VM_TRACE_MAP) |