FREE_OP1_IF_VAR();
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) {
- HashTable *properties;
- if (Z_OBJ_P(array_ptr)->properties
- && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
- if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
- GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+ zend_object *zobj = Z_OBJ_P(array_ptr);
+ if (!zobj->ce->get_iterator) {
- HashTable *properties;
-
- result = EX_VAR(opline->result.var);
- ZVAL_OBJ(result, zobj);
- if (OP1_TYPE != IS_TMP_VAR) {
- GC_ADDREF(zobj);
- }
- properties = zobj->properties;
++ HashTable *properties = zobj->properties;
+ if (properties) {
+ if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+ if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+ GC_DELREF(properties);
+ }
+ properties = zobj->properties = zend_array_dup(properties);
}
- Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+ } else {
+ properties = zobj->handlers->get_properties(zobj);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
- properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ ZEND_VM_C_GOTO(fe_reset_r_empty);
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (OP1_TYPE != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
FREE_OP1_IF_VAR();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
}
}
} else {
- zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+ zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
+ ZEND_VM_C_LABEL(fe_reset_r_empty):
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
FREE_OP1();
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) {
- HashTable *properties;
- if (Z_OBJ_P(array_ptr)->properties
- && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
- if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
- GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+ zend_object *zobj = Z_OBJ_P(array_ptr);
+ if (!zobj->ce->get_iterator) {
- HashTable *properties;
-
- result = EX_VAR(opline->result.var);
- ZVAL_OBJ(result, zobj);
- if (IS_CONST != IS_TMP_VAR) {
- GC_ADDREF(zobj);
- }
- properties = zobj->properties;
++ HashTable *properties = zobj->properties;
+ if (properties) {
+ if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+ if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+ GC_DELREF(properties);
+ }
+ properties = zobj->properties = zend_array_dup(properties);
}
- Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+ } else {
+ properties = zobj->handlers->get_properties(zobj);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
- properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CONST != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
}
}
} else {
- zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+ zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
+ fe_reset_r_empty:
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
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) {
- HashTable *properties;
- if (Z_OBJ_P(array_ptr)->properties
- && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
- if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
- GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+ zend_object *zobj = Z_OBJ_P(array_ptr);
+ if (!zobj->ce->get_iterator) {
- HashTable *properties;
-
- result = EX_VAR(opline->result.var);
- ZVAL_OBJ(result, zobj);
- if (IS_TMP_VAR != IS_TMP_VAR) {
- GC_ADDREF(zobj);
- }
- properties = zobj->properties;
++ HashTable *properties = zobj->properties;
+ if (properties) {
+ if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+ if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+ GC_DELREF(properties);
+ }
+ properties = zobj->properties = zend_array_dup(properties);
}
- Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+ } else {
+ properties = zobj->handlers->get_properties(zobj);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
- properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_TMP_VAR != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
}
}
} else {
- zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+ zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
+ fe_reset_r_empty:
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);
+ zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
}
}
Z_FE_POS_P(result) = 0;
- zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
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) {
- HashTable *properties;
- if (Z_OBJ_P(array_ptr)->properties
- && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
- if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
- GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+ zend_object *zobj = Z_OBJ_P(array_ptr);
+ if (!zobj->ce->get_iterator) {
- HashTable *properties;
-
- result = EX_VAR(opline->result.var);
- ZVAL_OBJ(result, zobj);
- if (IS_VAR != IS_TMP_VAR) {
- GC_ADDREF(zobj);
- }
- properties = zobj->properties;
++ HashTable *properties = zobj->properties;
+ if (properties) {
+ if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+ if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+ GC_DELREF(properties);
+ }
+ properties = zobj->properties = zend_array_dup(properties);
}
- Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+ } else {
+ properties = zobj->handlers->get_properties(zobj);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
- properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_VAR != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
- zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC);
}
}
} else {
- zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+ zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
+ fe_reset_r_empty:
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);
+ zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
}
}
}
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
- if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ }
+
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+ zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC);
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) {
- HashTable *properties;
- if (Z_OBJ_P(array_ptr)->properties
- && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) {
- if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) {
- GC_DELREF(Z_OBJ_P(array_ptr)->properties);
+ zend_object *zobj = Z_OBJ_P(array_ptr);
+ if (!zobj->ce->get_iterator) {
- HashTable *properties;
-
- result = EX_VAR(opline->result.var);
- ZVAL_OBJ(result, zobj);
- if (IS_CV != IS_TMP_VAR) {
- GC_ADDREF(zobj);
- }
- properties = zobj->properties;
++ HashTable *properties = zobj->properties;
+ if (properties) {
+ if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
+ if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
+ GC_DELREF(properties);
+ }
+ properties = zobj->properties = zend_array_dup(properties);
}
- Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
+ } else {
+ properties = zobj->handlers->get_properties(zobj);
}
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
+
- properties = Z_OBJPROP_P(array_ptr);
+ if (zend_hash_num_elements(properties) == 0) {
+ goto fe_reset_r_empty;
+ }
+
+ result = EX_VAR(opline->result.var);
+ ZVAL_COPY_VALUE(result, array_ptr);
+ if (IS_CV != IS_TMP_VAR) {
+ Z_ADDREF_P(array_ptr);
+ }
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
}
}
} else {
- zend_error(E_WARNING, "Invalid argument supplied for foreach()");
+ zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
+ fe_reset_r_empty:
ZVAL_UNDEF(EX_VAR(opline->result.var));
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;