@@ -4793,14 +4793,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
4793
4793
} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
4794
4794
zend_object *zobj = Z_OBJ_P(array_ptr);
4795
4795
if (!zobj->ce->get_iterator) {
4796
- HashTable *properties;
4797
-
4798
- result = EX_VAR(opline->result.var);
4799
- ZVAL_OBJ(result, zobj);
4800
- if (IS_CONST != IS_TMP_VAR) {
4801
- GC_ADDREF(zobj);
4802
- }
4803
- properties = zobj->properties;
4796
+ HashTable *properties = zobj->properties;
4804
4797
if (properties) {
4805
4798
if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
4806
4799
if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
@@ -4811,7 +4804,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
4811
4804
} else {
4812
4805
properties = zobj->handlers->get_properties(zobj);
4813
4806
}
4814
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
4807
+
4808
+ if (zend_hash_num_elements(properties) == 0) {
4809
+ goto fe_reset_r_empty;
4810
+ }
4811
+
4812
+ result = EX_VAR(opline->result.var);
4813
+ ZVAL_COPY_VALUE(result, array_ptr);
4814
+ if (IS_CONST != IS_TMP_VAR) {
4815
+ Z_ADDREF_P(array_ptr);
4816
+ }
4817
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
4815
4818
4816
4819
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4817
4820
} else {
@@ -4827,6 +4830,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER(
4827
4830
}
4828
4831
} else {
4829
4832
zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
4833
+ fe_reset_r_empty:
4830
4834
ZVAL_UNDEF(EX_VAR(opline->result.var));
4831
4835
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
4832
4836
@@ -4876,6 +4880,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
4876
4880
ZEND_VM_NEXT_OPCODE();
4877
4881
} else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
4878
4882
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
4883
+ HashTable *properties;
4879
4884
if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
4880
4885
if (array_ptr == array_ref) {
4881
4886
ZVAL_NEW_REF(array_ref, array_ref);
@@ -4894,7 +4899,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_
4894
4899
}
4895
4900
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
4896
4901
}
4897
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
4902
+
4903
+ properties = Z_OBJPROP_P(array_ptr);
4904
+ if (zend_hash_num_elements(properties) == 0) {
4905
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
4906
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
4907
+ }
4908
+
4909
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
4898
4910
4899
4911
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4900
4912
} else {
@@ -18788,14 +18800,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
18788
18800
} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
18789
18801
zend_object *zobj = Z_OBJ_P(array_ptr);
18790
18802
if (!zobj->ce->get_iterator) {
18791
- HashTable *properties;
18792
-
18793
- result = EX_VAR(opline->result.var);
18794
- ZVAL_OBJ(result, zobj);
18795
- if (IS_TMP_VAR != IS_TMP_VAR) {
18796
- GC_ADDREF(zobj);
18797
- }
18798
- properties = zobj->properties;
18803
+ HashTable *properties = zobj->properties;
18799
18804
if (properties) {
18800
18805
if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
18801
18806
if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
@@ -18806,7 +18811,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
18806
18811
} else {
18807
18812
properties = zobj->handlers->get_properties(zobj);
18808
18813
}
18809
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
18814
+
18815
+ if (zend_hash_num_elements(properties) == 0) {
18816
+ goto fe_reset_r_empty;
18817
+ }
18818
+
18819
+ result = EX_VAR(opline->result.var);
18820
+ ZVAL_COPY_VALUE(result, array_ptr);
18821
+ if (IS_TMP_VAR != IS_TMP_VAR) {
18822
+ Z_ADDREF_P(array_ptr);
18823
+ }
18824
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
18810
18825
18811
18826
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
18812
18827
} else {
@@ -18823,6 +18838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE
18823
18838
}
18824
18839
} else {
18825
18840
zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
18841
+ fe_reset_r_empty:
18826
18842
ZVAL_UNDEF(EX_VAR(opline->result.var));
18827
18843
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
18828
18844
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -18872,6 +18888,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
18872
18888
ZEND_VM_NEXT_OPCODE();
18873
18889
} else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
18874
18890
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
18891
+ HashTable *properties;
18875
18892
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
18876
18893
if (array_ptr == array_ref) {
18877
18894
ZVAL_NEW_REF(array_ref, array_ref);
@@ -18890,7 +18907,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z
18890
18907
}
18891
18908
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
18892
18909
}
18893
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
18910
+
18911
+ properties = Z_OBJPROP_P(array_ptr);
18912
+ if (zend_hash_num_elements(properties) == 0) {
18913
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
18914
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
18915
+ }
18916
+
18917
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
18894
18918
18895
18919
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
18896
18920
} else {
@@ -21338,14 +21362,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
21338
21362
} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
21339
21363
zend_object *zobj = Z_OBJ_P(array_ptr);
21340
21364
if (!zobj->ce->get_iterator) {
21341
- HashTable *properties;
21342
-
21343
- result = EX_VAR(opline->result.var);
21344
- ZVAL_OBJ(result, zobj);
21345
- if (IS_VAR != IS_TMP_VAR) {
21346
- GC_ADDREF(zobj);
21347
- }
21348
- properties = zobj->properties;
21365
+ HashTable *properties = zobj->properties;
21349
21366
if (properties) {
21350
21367
if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
21351
21368
if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
@@ -21356,8 +21373,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
21356
21373
} else {
21357
21374
properties = zobj->handlers->get_properties(zobj);
21358
21375
}
21359
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
21360
21376
21377
+ if (zend_hash_num_elements(properties) == 0) {
21378
+ goto fe_reset_r_empty;
21379
+ }
21380
+
21381
+ result = EX_VAR(opline->result.var);
21382
+ ZVAL_COPY_VALUE(result, array_ptr);
21383
+ if (IS_VAR != IS_TMP_VAR) {
21384
+ Z_ADDREF_P(array_ptr);
21385
+ }
21386
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
21361
21387
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
21362
21388
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
21363
21389
} else {
@@ -21374,6 +21400,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE
21374
21400
}
21375
21401
} else {
21376
21402
zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
21403
+ fe_reset_r_empty:
21377
21404
ZVAL_UNDEF(EX_VAR(opline->result.var));
21378
21405
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
21379
21406
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
@@ -21423,6 +21450,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
21423
21450
ZEND_VM_NEXT_OPCODE();
21424
21451
} else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
21425
21452
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
21453
+ HashTable *properties;
21426
21454
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
21427
21455
if (array_ptr == array_ref) {
21428
21456
ZVAL_NEW_REF(array_ref, array_ref);
@@ -21441,8 +21469,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z
21441
21469
}
21442
21470
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
21443
21471
}
21444
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
21445
21472
21473
+ properties = Z_OBJPROP_P(array_ptr);
21474
+ if (zend_hash_num_elements(properties) == 0) {
21475
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
21476
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
21477
+ }
21478
+
21479
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
21446
21480
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
21447
21481
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
21448
21482
} else {
@@ -38040,14 +38074,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
38040
38074
} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
38041
38075
zend_object *zobj = Z_OBJ_P(array_ptr);
38042
38076
if (!zobj->ce->get_iterator) {
38043
- HashTable *properties;
38044
-
38045
- result = EX_VAR(opline->result.var);
38046
- ZVAL_OBJ(result, zobj);
38047
- if (IS_CV != IS_TMP_VAR) {
38048
- GC_ADDREF(zobj);
38049
- }
38050
- properties = zobj->properties;
38077
+ HashTable *properties = zobj->properties;
38051
38078
if (properties) {
38052
38079
if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) {
38053
38080
if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) {
@@ -38058,7 +38085,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
38058
38085
} else {
38059
38086
properties = zobj->handlers->get_properties(zobj);
38060
38087
}
38061
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
38088
+
38089
+ if (zend_hash_num_elements(properties) == 0) {
38090
+ goto fe_reset_r_empty;
38091
+ }
38092
+
38093
+ result = EX_VAR(opline->result.var);
38094
+ ZVAL_COPY_VALUE(result, array_ptr);
38095
+ if (IS_CV != IS_TMP_VAR) {
38096
+ Z_ADDREF_P(array_ptr);
38097
+ }
38098
+ Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0);
38062
38099
38063
38100
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
38064
38101
} else {
@@ -38074,6 +38111,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN
38074
38111
}
38075
38112
} else {
38076
38113
zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_type_name(array_ptr));
38114
+ fe_reset_r_empty:
38077
38115
ZVAL_UNDEF(EX_VAR(opline->result.var));
38078
38116
Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1;
38079
38117
@@ -38123,6 +38161,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
38123
38161
ZEND_VM_NEXT_OPCODE();
38124
38162
} else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) {
38125
38163
if (!Z_OBJCE_P(array_ptr)->get_iterator) {
38164
+ HashTable *properties;
38126
38165
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
38127
38166
if (array_ptr == array_ref) {
38128
38167
ZVAL_NEW_REF(array_ref, array_ref);
@@ -38141,7 +38180,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE
38141
38180
}
38142
38181
Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties);
38143
38182
}
38144
- Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_OBJPROP_P(array_ptr), 0);
38183
+
38184
+ properties = Z_OBJPROP_P(array_ptr);
38185
+ if (zend_hash_num_elements(properties) == 0) {
38186
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1;
38187
+ ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
38188
+ }
38189
+
38190
+ Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0);
38145
38191
38146
38192
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
38147
38193
} else {
0 commit comments