Skip to content

Commit 6d298cc

Browse files
authored
Optimize spread operator for packed arrays (fix GH-9794) (#9796)
1 parent 44a2a9a commit 6d298cc

File tree

2 files changed

+62
-30
lines changed

2 files changed

+62
-30
lines changed

Zend/zend_vm_def.h

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6048,23 +6048,39 @@ ZEND_VM_C_LABEL(add_unpack_again):
60486048
if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) {
60496049
HashTable *ht = Z_ARRVAL_P(op1);
60506050
zval *val;
6051-
zend_string *key;
6051+
6052+
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
6053+
zend_hash_extend(result_ht, zend_hash_num_elements(result_ht) + zend_hash_num_elements(ht), 1);
6054+
ZEND_HASH_FILL_PACKED(result_ht) {
6055+
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
6056+
if (UNEXPECTED(Z_ISREF_P(val)) &&
6057+
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
6058+
val = Z_REFVAL_P(val);
6059+
}
6060+
Z_TRY_ADDREF_P(val);
6061+
ZEND_HASH_FILL_ADD(val);
6062+
} ZEND_HASH_FOREACH_END();
6063+
} ZEND_HASH_FILL_END();
6064+
} else {
6065+
zend_string *key;
60526066

6053-
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
6054-
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
6055-
val = Z_REFVAL_P(val);
6056-
}
6057-
Z_TRY_ADDREF_P(val);
6058-
if (key) {
6059-
zend_hash_update(result_ht, key, val);
6060-
} else {
6061-
if (!zend_hash_next_index_insert(result_ht, val)) {
6062-
zend_cannot_add_element();
6063-
zval_ptr_dtor_nogc(val);
6064-
break;
6067+
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
6068+
if (UNEXPECTED(Z_ISREF_P(val)) &&
6069+
UNEXPECTED(Z_REFCOUNT_P(val) == 1)) {
6070+
val = Z_REFVAL_P(val);
60656071
}
6066-
}
6067-
} ZEND_HASH_FOREACH_END();
6072+
Z_TRY_ADDREF_P(val);
6073+
if (key) {
6074+
zend_hash_update(result_ht, key, val);
6075+
} else {
6076+
if (!zend_hash_next_index_insert(result_ht, val)) {
6077+
zend_cannot_add_element();
6078+
zval_ptr_dtor_nogc(val);
6079+
break;
6080+
}
6081+
}
6082+
} ZEND_HASH_FOREACH_END();
6083+
}
60686084
} else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) {
60696085
zend_class_entry *ce = Z_OBJCE_P(op1);
60706086
zend_object_iterator *iter;

Zend/zend_vm_execute.h

Lines changed: 31 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)