SAVE_OPLINE();
var = EX_VAR(opline->op1.var);
- if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
{
USE_OPLINE
zend_free_op free_op1;
- zval *array_ptr;
+ zval *array_ptr, *result;
HashTable *fe_ht;
SAVE_OPLINE();
array_ptr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
- if (OP1_TYPE != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
- zend_bool is_empty;
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_POS_P(result) = 0;
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- FREE_OP1();
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ FREE_OP1_IF_VAR();
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashPosition pos = 0;
+ Bucket *p;
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (OP1_TYPE != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ pos = 0;
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+ FREE_OP1_IF_VAR();
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
}
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ FREE_OP1_IF_VAR();
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ FREE_OP1();
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
+ }
+
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ FREE_OP1();
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(&iter->std);
FREE_OP1();
HANDLE_EXCEPTION();
}
- }
-
- is_empty = iter->funcs->valid(iter) != SUCCESS;
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- FREE_OP1();
- HANDLE_EXCEPTION();
- }
- iter->index = -1; /* will be set to 0 before using next handler */
+ iter->index = -1; /* will be set to 0 before using next handler */
- ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
- FREE_OP1();
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- zval *result = EX_VAR(opline->result.var);
-
- ZVAL_COPY_VALUE(result, array_ptr);
- if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(array_ptr);
+ FREE_OP1();
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
}
- Z_FE_POS_P(result) = 0;
-
- FREE_OP1_IF_VAR();
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
FREE_OP1();
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
zend_free_op free_op1;
zval *array_ptr, *array_ref;
HashTable *fe_ht;
+ HashPosition pos = 0;
+ Bucket *p;
SAVE_OPLINE();
array_ref = array_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
}
- if (OP1_TYPE != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
- zend_bool is_empty;
-
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- if (OP1_TYPE == IS_VAR) {
- FREE_OP1_VAR_PTR();
- } else {
- FREE_OP1();
- }
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
- }
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
-
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (OP1_TYPE == IS_VAR) {
- FREE_OP1_VAR_PTR();
- } else {
- FREE_OP1();
- }
- HANDLE_EXCEPTION();
- }
- }
-
- is_empty = iter->funcs->valid(iter) != SUCCESS;
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (OP1_TYPE == IS_VAR) {
- FREE_OP1_VAR_PTR();
- } else {
- FREE_OP1();
- }
- HANDLE_EXCEPTION();
- }
- 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;
-
- if (OP1_TYPE == IS_VAR) {
- FREE_OP1_VAR_PTR();
- } else {
- FREE_OP1();
- }
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- HashPosition pos = 0;
- Bucket *p;
-
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
if (array_ptr == array_ref) {
ZVAL_NEW_REF(array_ref, array_ref);
array_ptr = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(array_ptr, array_ref);
}
- if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
- if (OP1_TYPE == IS_CONST) {
- zval_copy_ctor_func(array_ptr);
- } else {
- SEPARATE_ARRAY(array_ptr);
- }
- fe_ht = Z_ARRVAL_P(array_ptr);
+ if (OP1_TYPE == IS_CONST) {
+ zval_copy_ctor_func(array_ptr);
+ } else {
+ SEPARATE_ARRAY(array_ptr);
}
+ fe_ht = Z_ARRVAL_P(array_ptr);
while (1) {
if (pos >= fe_ht->nNumUsed) {
FREE_OP1_VAR_PTR();
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
p = fe_ht->arData + pos;
- if ((Z_TYPE(p->val) != IS_UNDEF &&
- (Z_TYPE(p->val) != IS_INDIRECT ||
- Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
- (Z_TYPE_P(array_ptr) != IS_OBJECT ||
- !p->key ||
- zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ if (Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) {
break;
}
pos++;
FREE_OP1_VAR_PTR();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
+ } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
+ if (array_ptr == array_ref) {
+ ZVAL_NEW_REF(array_ref, array_ref);
+ array_ptr = Z_REFVAL_P(array_ref);
+ }
+ Z_ADDREF_P(array_ref);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+ } else {
+ array_ptr = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(array_ptr, array_ref);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+ FREE_OP1_VAR_PTR();
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
+ }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ FREE_OP1_VAR_PTR();
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ if (OP1_TYPE == IS_VAR) {
+ FREE_OP1_VAR_PTR();
+ } else {
+ FREE_OP1();
+ }
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
+ }
+
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (OP1_TYPE == IS_VAR) {
+ FREE_OP1_VAR_PTR();
+ } else {
+ FREE_OP1();
+ }
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (OP1_TYPE == IS_VAR) {
+ FREE_OP1_VAR_PTR();
+ } else {
+ FREE_OP1();
+ }
+ HANDLE_EXCEPTION();
+ }
+ 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;
+
+ if (OP1_TYPE == IS_VAR) {
+ FREE_OP1_VAR_PTR();
+ } else {
+ FREE_OP1();
+ }
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
zend_object *zobj = Z_OBJ_P(array);
fe_ht = Z_OBJPROP_P(array);
- pos = Z_FE_POS_P(EX_VAR(opline->op1.var));
+ pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
while (1) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
}
}
ZVAL_COPY(EX_VAR(opline->result.var), value);
- Z_FE_POS_P(EX_VAR(opline->op1.var)) = pos + 1;
+ while (1) {
+ pos++;
+ if (pos >= fe_ht->nNumUsed) {
+ pos = INVALID_IDX;
+ break;
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (Z_TYPE_P(array) != IS_OBJECT ||
+ !p->key ||
+ zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
+ break;
+ }
+ }
+ EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos =
+ fe_ht->nInternalPointer = pos;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
} else {
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
} else if (brk_opline->opcode == ZEND_FE_FREE) {
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
zval *var = EX_VAR(brk_opline->op1.var);
- if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);
{
USE_OPLINE
- zval *array_ptr;
+ zval *array_ptr, *result;
HashTable *fe_ht;
SAVE_OPLINE();
array_ptr = EX_CONSTANT(opline->op1);
- if (IS_CONST != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
- zend_bool is_empty;
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_POS_P(result) = 0;
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashPosition pos = 0;
+ Bucket *p;
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CONST != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ pos = 0;
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
}
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
HANDLE_EXCEPTION();
}
- }
- is_empty = iter->funcs->valid(iter) != SUCCESS;
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
+ HANDLE_EXCEPTION();
+ }
+ }
- HANDLE_EXCEPTION();
- }
- iter->index = -1; /* will be set to 0 before using next handler */
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
- ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- zval *result = EX_VAR(opline->result.var);
+ HANDLE_EXCEPTION();
+ }
+ iter->index = -1; /* will be set to 0 before using next handler */
- ZVAL_COPY_VALUE(result, array_ptr);
- if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(array_ptr);
- }
- Z_FE_POS_P(result) = 0;
+ ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
zval *array_ptr, *array_ref;
HashTable *fe_ht;
+ HashPosition pos = 0;
+ Bucket *p;
SAVE_OPLINE();
array_ref = array_ptr = EX_CONSTANT(opline->op1);
}
- if (IS_CONST != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
- zend_bool is_empty;
-
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- if (IS_CONST == IS_VAR) {
-
- } else {
-
- }
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
- }
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
-
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (IS_CONST == IS_VAR) {
-
- } else {
-
- }
- HANDLE_EXCEPTION();
- }
- }
-
- is_empty = iter->funcs->valid(iter) != SUCCESS;
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (IS_CONST == IS_VAR) {
-
- } else {
-
- }
- HANDLE_EXCEPTION();
- }
- 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;
-
- if (IS_CONST == IS_VAR) {
-
- } else {
-
- }
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- HashPosition pos = 0;
- Bucket *p;
-
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
if (array_ptr == array_ref) {
ZVAL_NEW_REF(array_ref, array_ref);
array_ptr = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(array_ptr, array_ref);
}
- if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
- if (IS_CONST == IS_CONST) {
- zval_copy_ctor_func(array_ptr);
- } else {
- SEPARATE_ARRAY(array_ptr);
- }
- fe_ht = Z_ARRVAL_P(array_ptr);
+ if (IS_CONST == IS_CONST) {
+ zval_copy_ctor_func(array_ptr);
+ } else {
+ SEPARATE_ARRAY(array_ptr);
}
+ fe_ht = Z_ARRVAL_P(array_ptr);
while (1) {
if (pos >= fe_ht->nNumUsed) {
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
p = fe_ht->arData + pos;
- if ((Z_TYPE(p->val) != IS_UNDEF &&
- (Z_TYPE(p->val) != IS_INDIRECT ||
- Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
- (Z_TYPE_P(array_ptr) != IS_OBJECT ||
- !p->key ||
- zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ if (Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) {
break;
}
pos++;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
+ } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
+ if (array_ptr == array_ref) {
+ ZVAL_NEW_REF(array_ref, array_ref);
+ array_ptr = Z_REFVAL_P(array_ref);
+ }
+ Z_ADDREF_P(array_ref);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+ } else {
+ array_ptr = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(array_ptr, array_ref);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
+ }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ if (IS_CONST == IS_VAR) {
+
+ } else {
+
+ }
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
+ }
+
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_CONST == IS_VAR) {
+
+ } else {
+
+ }
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_CONST == IS_VAR) {
+
+ } else {
+
+ }
+ HANDLE_EXCEPTION();
+ }
+ 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;
+
+ if (IS_CONST == IS_VAR) {
+
+ } else {
+
+ }
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
{
USE_OPLINE
zend_free_op free_op1;
- zval *array_ptr;
+ zval *array_ptr, *result;
HashTable *fe_ht;
SAVE_OPLINE();
array_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
- if (IS_TMP_VAR != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
- zend_bool is_empty;
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_POS_P(result) = 0;
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- zval_ptr_dtor_nogc(free_op1);
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashPosition pos = 0;
+ Bucket *p;
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_TMP_VAR != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ pos = 0;
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
}
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
zval_ptr_dtor_nogc(free_op1);
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
HANDLE_EXCEPTION();
}
- }
- is_empty = iter->funcs->valid(iter) != SUCCESS;
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ zval_ptr_dtor_nogc(free_op1);
+ HANDLE_EXCEPTION();
+ }
+ }
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- zval_ptr_dtor_nogc(free_op1);
- HANDLE_EXCEPTION();
- }
- iter->index = -1; /* will be set to 0 before using next handler */
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
- ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ zval_ptr_dtor_nogc(free_op1);
+ HANDLE_EXCEPTION();
+ }
+ iter->index = -1; /* will be set to 0 before using next handler */
- zval_ptr_dtor_nogc(free_op1);
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- zval *result = EX_VAR(opline->result.var);
+ ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
- ZVAL_COPY_VALUE(result, array_ptr);
- if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(array_ptr);
+ zval_ptr_dtor_nogc(free_op1);
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
}
- Z_FE_POS_P(result) = 0;
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
zend_free_op free_op1;
zval *array_ptr, *array_ref;
HashTable *fe_ht;
+ HashPosition pos = 0;
+ Bucket *p;
SAVE_OPLINE();
array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);
}
- if (IS_TMP_VAR != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
- zend_bool is_empty;
-
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- if (IS_TMP_VAR == IS_VAR) {
-
- } else {
- zval_ptr_dtor_nogc(free_op1);
- }
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
- }
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
-
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (IS_TMP_VAR == IS_VAR) {
-
- } else {
- zval_ptr_dtor_nogc(free_op1);
- }
- HANDLE_EXCEPTION();
- }
- }
-
- is_empty = iter->funcs->valid(iter) != SUCCESS;
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (IS_TMP_VAR == IS_VAR) {
-
- } else {
- zval_ptr_dtor_nogc(free_op1);
- }
- HANDLE_EXCEPTION();
- }
- 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;
-
- if (IS_TMP_VAR == IS_VAR) {
-
- } else {
- zval_ptr_dtor_nogc(free_op1);
- }
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- HashPosition pos = 0;
- Bucket *p;
-
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
if (array_ptr == array_ref) {
ZVAL_NEW_REF(array_ref, array_ref);
array_ptr = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(array_ptr, array_ref);
}
- if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
- if (IS_TMP_VAR == IS_CONST) {
- zval_copy_ctor_func(array_ptr);
- } else {
- SEPARATE_ARRAY(array_ptr);
- }
- fe_ht = Z_ARRVAL_P(array_ptr);
+ if (IS_TMP_VAR == IS_CONST) {
+ zval_copy_ctor_func(array_ptr);
+ } else {
+ SEPARATE_ARRAY(array_ptr);
}
+ fe_ht = Z_ARRVAL_P(array_ptr);
while (1) {
if (pos >= fe_ht->nNumUsed) {
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
p = fe_ht->arData + pos;
- if ((Z_TYPE(p->val) != IS_UNDEF &&
- (Z_TYPE(p->val) != IS_INDIRECT ||
- Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
- (Z_TYPE_P(array_ptr) != IS_OBJECT ||
- !p->key ||
- zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ if (Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) {
break;
}
pos++;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
+ } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
+ if (array_ptr == array_ref) {
+ ZVAL_NEW_REF(array_ref, array_ref);
+ array_ptr = Z_REFVAL_P(array_ref);
+ }
+ Z_ADDREF_P(array_ref);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+ } else {
+ array_ptr = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(array_ptr, array_ref);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
+ }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ if (IS_TMP_VAR == IS_VAR) {
+
+ } else {
+ zval_ptr_dtor_nogc(free_op1);
+ }
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
+ }
+
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_TMP_VAR == IS_VAR) {
+
+ } else {
+ zval_ptr_dtor_nogc(free_op1);
+ }
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_TMP_VAR == IS_VAR) {
+
+ } else {
+ zval_ptr_dtor_nogc(free_op1);
+ }
+ HANDLE_EXCEPTION();
+ }
+ 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;
+
+ if (IS_TMP_VAR == IS_VAR) {
+
+ } else {
+ zval_ptr_dtor_nogc(free_op1);
+ }
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
{
USE_OPLINE
zend_free_op free_op1;
- zval *array_ptr;
+ zval *array_ptr, *result;
HashTable *fe_ht;
SAVE_OPLINE();
array_ptr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);
- if (IS_VAR != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
- zend_bool is_empty;
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_POS_P(result) = 0;
+
+ zval_ptr_dtor_nogc(free_op1);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashPosition pos = 0;
+ Bucket *p;
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_VAR != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ pos = 0;
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+ zval_ptr_dtor_nogc(free_op1);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
+ }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
zval_ptr_dtor_nogc(free_op1);
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ zval_ptr_dtor_nogc(free_op1);
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
}
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ zval_ptr_dtor_nogc(free_op1);
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
+
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(&iter->std);
zval_ptr_dtor_nogc(free_op1);
HANDLE_EXCEPTION();
}
- }
+ iter->index = -1; /* will be set to 0 before using next handler */
- is_empty = iter->funcs->valid(iter) != SUCCESS;
+ ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
zval_ptr_dtor_nogc(free_op1);
- HANDLE_EXCEPTION();
- }
- iter->index = -1; /* will be set to 0 before using next handler */
-
- ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
-
- zval_ptr_dtor_nogc(free_op1);
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- zval *result = EX_VAR(opline->result.var);
-
- ZVAL_COPY_VALUE(result, array_ptr);
- if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(array_ptr);
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
}
- Z_FE_POS_P(result) = 0;
-
- zval_ptr_dtor_nogc(free_op1);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
zval_ptr_dtor_nogc(free_op1);
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
zend_free_op free_op1;
zval *array_ptr, *array_ref;
HashTable *fe_ht;
+ HashPosition pos = 0;
+ Bucket *p;
SAVE_OPLINE();
array_ref = array_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
}
- if (IS_VAR != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
- zend_bool is_empty;
-
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- if (IS_VAR == IS_VAR) {
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+ if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
+ if (array_ptr == array_ref) {
+ ZVAL_NEW_REF(array_ref, array_ref);
+ array_ptr = Z_REFVAL_P(array_ref);
+ }
+ Z_ADDREF_P(array_ref);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+ } else {
+ array_ptr = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(array_ptr, array_ref);
+ }
+ if (IS_VAR == IS_CONST) {
+ zval_copy_ctor_func(array_ptr);
+ } else {
+ SEPARATE_ARRAY(array_ptr);
+ }
+ fe_ht = Z_ARRVAL_P(array_ptr);
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- } else {
- zval_ptr_dtor_nogc(free_op1);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ p = fe_ht->arData + pos;
+ if (Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) {
+ break;
}
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
+ pos++;
}
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
+ if (array_ptr == array_ref) {
+ ZVAL_NEW_REF(array_ref, array_ref);
+ array_ptr = Z_REFVAL_P(array_ref);
+ }
+ Z_ADDREF_P(array_ref);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+ } else {
+ array_ptr = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(array_ptr, array_ref);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+ if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
+ }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ if (IS_VAR == IS_VAR) {
+ if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
+ } else {
+ zval_ptr_dtor_nogc(free_op1);
+ }
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
+ }
+
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_VAR == IS_VAR) {
+ if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
+ } else {
+ zval_ptr_dtor_nogc(free_op1);
+ }
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
if (UNEXPECTED(EG(exception) != NULL)) {
OBJ_RELEASE(&iter->std);
if (IS_VAR == IS_VAR) {
}
HANDLE_EXCEPTION();
}
- }
+ iter->index = -1; /* will be set to 0 before using next handler */
- is_empty = iter->funcs->valid(iter) != SUCCESS;
+ ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
if (IS_VAR == IS_VAR) {
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
} else {
zval_ptr_dtor_nogc(free_op1);
}
- HANDLE_EXCEPTION();
- }
- 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;
-
- if (IS_VAR == IS_VAR) {
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- } else {
- zval_ptr_dtor_nogc(free_op1);
- }
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- HashPosition pos = 0;
- Bucket *p;
-
- if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- if (array_ptr == array_ref) {
- ZVAL_NEW_REF(array_ref, array_ref);
- array_ptr = Z_REFVAL_P(array_ref);
- }
- Z_ADDREF_P(array_ref);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
- } else {
- array_ptr = EX_VAR(opline->result.var);
- ZVAL_COPY_VALUE(array_ptr, array_ref);
- }
- if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
- if (IS_VAR == IS_CONST) {
- zval_copy_ctor_func(array_ptr);
- } else {
- SEPARATE_ARRAY(array_ptr);
- }
- fe_ht = Z_ARRVAL_P(array_ptr);
- }
- while (1) {
- if (pos >= fe_ht->nNumUsed) {
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ if (is_empty) {
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- p = fe_ht->arData + pos;
- if ((Z_TYPE(p->val) != IS_UNDEF &&
- (Z_TYPE(p->val) != IS_INDIRECT ||
- Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
- (Z_TYPE_P(array_ptr) != IS_OBJECT ||
- !p->key ||
- zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
- break;
- }
- pos++;
}
- fe_ht->nInternalPointer = pos;
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
-
- if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
zend_object *zobj = Z_OBJ_P(array);
fe_ht = Z_OBJPROP_P(array);
- pos = Z_FE_POS_P(EX_VAR(opline->op1.var));
+ pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht);
while (1) {
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
/* reached end of iteration */
}
}
ZVAL_COPY(EX_VAR(opline->result.var), value);
- Z_FE_POS_P(EX_VAR(opline->op1.var)) = pos + 1;
+ while (1) {
+ pos++;
+ if (pos >= fe_ht->nNumUsed) {
+ pos = INVALID_IDX;
+ break;
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (Z_TYPE_P(array) != IS_OBJECT ||
+ !p->key ||
+ zend_check_property_access(Z_OBJ_P(array), p->key) == SUCCESS)) {
+ break;
+ }
+ }
+ EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos =
+ fe_ht->nInternalPointer = pos;
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
} else {
{
USE_OPLINE
- zval *array_ptr;
+ zval *array_ptr, *result;
HashTable *fe_ht;
SAVE_OPLINE();
array_ptr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);
- if (IS_CV != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
- zend_bool is_empty;
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_POS_P(result) = 0;
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ HashPosition pos = 0;
+ Bucket *p;
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CV != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ pos = 0;
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
}
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 0);
+ zend_bool is_empty;
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
HANDLE_EXCEPTION();
}
- }
- is_empty = iter->funcs->valid(iter) != SUCCESS;
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
+ HANDLE_EXCEPTION();
+ }
+ }
- HANDLE_EXCEPTION();
- }
- iter->index = -1; /* will be set to 0 before using next handler */
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
- ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- zval *result = EX_VAR(opline->result.var);
+ HANDLE_EXCEPTION();
+ }
+ iter->index = -1; /* will be set to 0 before using next handler */
- ZVAL_COPY_VALUE(result, array_ptr);
- if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) {
- Z_ADDREF_P(array_ptr);
- }
- Z_FE_POS_P(result) = 0;
+ ZVAL_OBJ(EX_VAR(opline->result.var), &iter->std);
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
zval *array_ptr, *array_ref;
HashTable *fe_ht;
+ HashPosition pos = 0;
+ Bucket *p;
SAVE_OPLINE();
array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var);
}
- if (IS_CV != IS_CONST &&
- Z_TYPE_P(array_ptr) == IS_OBJECT && Z_OBJCE_P(array_ptr)->get_iterator) {
- zend_class_entry *ce = Z_OBJCE_P(array_ptr);
- zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
- zend_bool is_empty;
-
- if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
- if (IS_CV == IS_VAR) {
-
- } else {
-
- }
- if (!EG(exception)) {
- zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
- }
- zend_throw_exception_internal(NULL);
- HANDLE_EXCEPTION();
- }
-
- iter->index = 0;
- if (iter->funcs->rewind) {
- iter->funcs->rewind(iter);
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (IS_CV == IS_VAR) {
-
- } else {
-
- }
- HANDLE_EXCEPTION();
- }
- }
-
- is_empty = iter->funcs->valid(iter) != SUCCESS;
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- OBJ_RELEASE(&iter->std);
- if (IS_CV == IS_VAR) {
-
- } else {
-
- }
- HANDLE_EXCEPTION();
- }
- 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;
-
- if (IS_CV == IS_VAR) {
-
- } else {
-
- }
- if (is_empty) {
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
- } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) {
- HashPosition pos = 0;
- Bucket *p;
-
+ if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) {
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
if (array_ptr == array_ref) {
ZVAL_NEW_REF(array_ref, array_ref);
array_ptr = EX_VAR(opline->result.var);
ZVAL_COPY_VALUE(array_ptr, array_ref);
}
- if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
- if (IS_CV == IS_CONST) {
- zval_copy_ctor_func(array_ptr);
- } else {
- SEPARATE_ARRAY(array_ptr);
- }
- fe_ht = Z_ARRVAL_P(array_ptr);
+ if (IS_CV == IS_CONST) {
+ zval_copy_ctor_func(array_ptr);
+ } else {
+ SEPARATE_ARRAY(array_ptr);
}
+ fe_ht = Z_ARRVAL_P(array_ptr);
while (1) {
if (pos >= fe_ht->nNumUsed) {
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
p = fe_ht->arData + pos;
- if ((Z_TYPE(p->val) != IS_UNDEF &&
- (Z_TYPE(p->val) != IS_INDIRECT ||
- Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
- (Z_TYPE_P(array_ptr) != IS_OBJECT ||
- !p->key ||
- zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ if (Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) {
break;
}
pos++;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
+ } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
+ if (!Z_OBJCE_P(array_ptr)->get_iterator) {
+ if (IS_CV == IS_VAR || IS_CV == IS_CV) {
+ if (array_ptr == array_ref) {
+ ZVAL_NEW_REF(array_ref, array_ref);
+ array_ptr = Z_REFVAL_P(array_ref);
+ }
+ Z_ADDREF_P(array_ref);
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref);
+ } else {
+ array_ptr = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(array_ptr, array_ref);
+ }
+ fe_ht = Z_OBJPROP_P(array_ptr);
+ while (1) {
+ if (pos >= fe_ht->nNumUsed) {
+
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+ p = fe_ht->arData + pos;
+ if ((Z_TYPE(p->val) != IS_UNDEF &&
+ (Z_TYPE(p->val) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT(p->val)) != IS_UNDEF)) &&
+ (!p->key ||
+ zend_check_property_access(Z_OBJ_P(array_ptr), p->key) == SUCCESS)) {
+ break;
+ }
+ pos++;
+ }
+ fe_ht->nInternalPointer = pos;
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(fe_ht);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_class_entry *ce = Z_OBJCE_P(array_ptr);
+ zend_object_iterator *iter = ce->get_iterator(ce, array_ptr, 1);
+ zend_bool is_empty;
+
+ if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) {
+ if (IS_CV == IS_VAR) {
+
+ } else {
+
+ }
+ if (!EG(exception)) {
+ zend_throw_exception_ex(NULL, 0, "Object of type %s did not create an Iterator", ce->name->val);
+ }
+ zend_throw_exception_internal(NULL);
+ HANDLE_EXCEPTION();
+ }
+
+ iter->index = 0;
+ if (iter->funcs->rewind) {
+ iter->funcs->rewind(iter);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_CV == IS_VAR) {
+
+ } else {
+
+ }
+ HANDLE_EXCEPTION();
+ }
+ }
+
+ is_empty = iter->funcs->valid(iter) != SUCCESS;
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ OBJ_RELEASE(&iter->std);
+ if (IS_CV == IS_VAR) {
+
+ } else {
+
+ }
+ HANDLE_EXCEPTION();
+ }
+ 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;
+
+ if (IS_CV == IS_VAR) {
+
+ } else {
+
+ }
+ if (is_empty) {
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ } else {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
} else {
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
ZVAL_UNDEF(EX_VAR(opline->result.var));
SAVE_OPLINE();
var = EX_VAR(opline->op1.var);
- if (Z_FE_ITER_P(var) != (uint32_t)-1) {
+ if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
zend_hash_iterator_del(Z_FE_ITER_P(var));
}
zval_ptr_dtor_nogc(var);