Skip to content

Commit ea75120

Browse files
committed
mirror in cpp
1 parent 7fcb343 commit ea75120

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

‎turbo-ext/src/ConstantArrayType.cpp‎

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,12 @@ class ConstantArrayType
16581658
zval *k = keyTypes();
16591659
zval *v = k != NULL ? valueTypes() : NULL;
16601660
if (UNEXPECTED(result.isUndef() || v == NULL)) return zv::Val();
1661+
/* $acceptsValueCache = [] — keyed by both object handles in one
1662+
* integer instead of the twin's 'id-id' string */
1663+
zval acceptsValueCacheZv;
1664+
array_init(&acceptsValueCacheZv);
1665+
zv::Val acceptsValueCacheHolder = zv::Val::adopt(acceptsValueCacheZv);
1666+
HashTable *acceptsValueCache = Z_ARRVAL(acceptsValueCacheZv);
16611667
for (zv::ArrayEntry entry : zv::ArrRef(k)) {
16621668
zend_long i = (zend_long) entry.indexKey();
16631669
zval *keyType = entry.value().deref().raw();
@@ -1702,11 +1708,34 @@ class ConstantArrayType
17021708
if (UNEXPECTED(result.isUndef())) return zv::Val();
17031709
zv::Val otherValueType = callType(Z_OBJ_P(type), PT_LC("getoffsetvaluetype"), 1, keyType);
17041710
if (UNEXPECTED(otherValueType.isUndef())) return zv::Val();
1711+
zend_ulong acceptsValueCacheKey = ((zend_ulong) Z_OBJ_HANDLE_P(valueType) << 32) | (zend_ulong) Z_OBJ_HANDLE_P(otherValueType.raw());
1712+
zv::Val acceptsValue;
1713+
zval *acceptsValueCached = zend_hash_index_find(acceptsValueCache, acceptsValueCacheKey);
1714+
if (acceptsValueCached != NULL) {
1715+
acceptsValue = zv::Val::copyOf(zv::Ref(zend_hash_index_find(Z_ARRVAL_P(acceptsValueCached), 1)));
1716+
} else {
1717+
zv::Args args{otherValueType.raw(), strictTypes};
1718+
acceptsValue = pt_type_op(Z_OBJ_P(valueType), PT_OP_ACCEPTS, 2, args);
1719+
if (UNEXPECTED(acceptsValue.isUndef())) return zv::Val();
1720+
/* $otherValueType is kept alive so that its id is not reused */
1721+
zval pair;
1722+
array_init_size(&pair, 2);
1723+
Z_TRY_ADDREF_P(otherValueType.raw());
1724+
add_next_index_zval(&pair, otherValueType.raw());
1725+
Z_TRY_ADDREF_P(acceptsValue.raw());
1726+
add_next_index_zval(&pair, acceptsValue.raw());
1727+
zend_hash_index_update(acceptsValueCache, acceptsValueCacheKey, &pair);
1728+
}
1729+
/* $acceptsValue->yes() && count($acceptsValue->reasons) === 0: continue */
1730+
zend_long acceptsValueBefore = pt_type_result_trinary(acceptsValue.raw());
1731+
if (UNEXPECTED(acceptsValueBefore < 0)) return zv::Val();
1732+
if (acceptsValueBefore == PT_TRI_YES) {
1733+
zv::Val acceptsValueReasons = resultReasons(acceptsValue.raw());
1734+
if (UNEXPECTED(acceptsValueReasons.isUndef())) return zv::Val();
1735+
if (arrayCount(acceptsValueReasons.raw()) == 0) continue;
1736+
}
17051737
zv::Val verbosity = pt_type_verbosity_recommended(valueType, otherValueType.raw());
17061738
if (UNEXPECTED(verbosity.isUndef())) return zv::Val();
1707-
zv::Args args{otherValueType.raw(), strictTypes};
1708-
zv::Val acceptsValue = pt_type_op(Z_OBJ_P(valueType), PT_OP_ACCEPTS, 2, args);
1709-
if (UNEXPECTED(acceptsValue.isUndef())) return zv::Val();
17101739
zv::Val captured = quadOf(keyType, valueType, verbosity.raw(), otherValueType.raw());
17111740
acceptsValue = decorateReasons(acceptsValue.raw(), offsetReasonCallback, captured.raw(), NULL);
17121741
if (UNEXPECTED(acceptsValue.isUndef())) return zv::Val();

0 commit comments

Comments
 (0)