@@ -1640,57 +1640,6 @@ static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry
16401640}
16411641/* }}} */
16421642
1643- // TODO Merge with the one in zend_compile
1644- static void zend_types_ht_dtor (zval * ptr ) {
1645- zend_type * type = Z_PTR_P (ptr );
1646- // TODO Figure out persistency?
1647- zend_type_release (* type , false);
1648- efree (type );
1649- }
1650-
1651- static void interface_bind_generic_types_for_interfaces (zend_class_entry * ce , const zend_class_entry * iface ) {
1652- zend_string * iface_lc_name = zend_string_tolower (iface -> name );
1653- const HashTable * ce_bound_types = ce -> bound_types ? zend_hash_find_ptr (ce -> bound_types , iface_lc_name ) : NULL ;
1654- for (uint32_t i = 0 ; i < iface -> num_interfaces ; i ++ ) {
1655- zend_class_entry * entry = iface -> interfaces [i ];
1656- /* Bind generic types */
1657- /* We need to propagate the bound generic parameters to the inherited interfaces */
1658- if (entry -> num_generic_parameters == 0 ) {
1659- continue ;
1660- }
1661- zend_string * inherited_iface_lc_name = zend_string_tolower (entry -> name );
1662- const HashTable * interface_bound_types = zend_hash_find_ptr (iface -> bound_types , inherited_iface_lc_name );
1663- HashTable * ce_bound_types_to_inherited_iface = zend_hash_find_ptr (ce -> bound_types , inherited_iface_lc_name );
1664- ZEND_ASSERT (interface_bound_types != NULL && "This must exist at this point" );
1665- if (ce_bound_types_to_inherited_iface == NULL ) {
1666- ALLOC_HASHTABLE (ce_bound_types_to_inherited_iface );
1667- zend_hash_init (ce_bound_types_to_inherited_iface , entry -> num_generic_parameters , NULL , zend_types_ht_dtor , false /* todo depend on internal or not */ );
1668- zend_hash_add_new_ptr (ce -> bound_types , inherited_iface_lc_name , ce_bound_types_to_inherited_iface );
1669- }
1670- for (
1671- uint32_t inherited_iface_generic_param_index = 0 ;
1672- inherited_iface_generic_param_index < entry -> num_generic_parameters ;
1673- inherited_iface_generic_param_index ++
1674- ) {
1675- const zend_generic_parameter * inherited_generic_parameter = & entry -> generic_parameters [inherited_iface_generic_param_index ];
1676- const zend_type * iface_bound_type_ptr = zend_hash_index_find_ptr (interface_bound_types , inherited_iface_generic_param_index );
1677- ZEND_ASSERT (iface_bound_type_ptr != NULL );
1678- zend_type bound_type ;
1679- if (ZEND_TYPE_IS_ASSOCIATED (* iface_bound_type_ptr )) {
1680- memcpy (& bound_type , zend_hash_find_ptr (ce_bound_types , ZEND_TYPE_NAME (* iface_bound_type_ptr )), sizeof (zend_type ));
1681- } else {
1682- bound_type = * iface_bound_type_ptr ;
1683- }
1684- /* Deep type copy */
1685- zend_type_copy_ctor (& bound_type , true, false);
1686- zend_hash_add_mem (ce_bound_types_to_inherited_iface , inherited_generic_parameter -> name ,
1687- & bound_type , sizeof (bound_type ));
1688- }
1689- zend_string_release_ex (inherited_iface_lc_name , false);
1690- }
1691- zend_string_release_ex (iface_lc_name , false);
1692- }
1693-
16941643static void zend_do_inherit_interfaces (zend_class_entry * ce , const zend_class_entry * iface ) /* {{{ */
16951644{
16961645 /* expects interface to be contained in ce's interface list already */
@@ -2249,6 +2198,57 @@ static void do_inherit_iface_constant(zend_string *name, zend_class_constant *c,
22492198}
22502199/* }}} */
22512200
2201+ // TODO Merge with the one in zend_compile
2202+ static void zend_types_ht_dtor (zval * ptr ) {
2203+ zend_type * type = Z_PTR_P (ptr );
2204+ // TODO Figure out persistency?
2205+ zend_type_release (* type , false);
2206+ efree (type );
2207+ }
2208+
2209+ ZEND_ATTRIBUTE_NONNULL static void bind_generic_types_for_inherited_interfaces (zend_class_entry * ce , const zend_class_entry * iface ) {
2210+ zend_string * iface_lc_name = zend_string_tolower (iface -> name );
2211+ const HashTable * ce_bound_types = ce -> bound_types ? zend_hash_find_ptr (ce -> bound_types , iface_lc_name ) : NULL ;
2212+ for (uint32_t i = 0 ; i < iface -> num_interfaces ; i ++ ) {
2213+ zend_class_entry * entry = iface -> interfaces [i ];
2214+ /* Bind generic types */
2215+ /* We need to propagate the bound generic parameters to the inherited interfaces */
2216+ if (entry -> num_generic_parameters == 0 ) {
2217+ continue ;
2218+ }
2219+ zend_string * inherited_iface_lc_name = zend_string_tolower (entry -> name );
2220+ const HashTable * interface_bound_types = zend_hash_find_ptr (iface -> bound_types , inherited_iface_lc_name );
2221+ HashTable * ce_bound_types_to_inherited_iface = zend_hash_find_ptr (ce -> bound_types , inherited_iface_lc_name );
2222+ ZEND_ASSERT (interface_bound_types != NULL && "This must exist at this point" );
2223+ if (ce_bound_types_to_inherited_iface == NULL ) {
2224+ ALLOC_HASHTABLE (ce_bound_types_to_inherited_iface );
2225+ zend_hash_init (ce_bound_types_to_inherited_iface , entry -> num_generic_parameters , NULL , zend_types_ht_dtor , false /* todo depend on internal or not */ );
2226+ zend_hash_add_new_ptr (ce -> bound_types , inherited_iface_lc_name , ce_bound_types_to_inherited_iface );
2227+ }
2228+ for (
2229+ uint32_t inherited_iface_generic_param_index = 0 ;
2230+ inherited_iface_generic_param_index < entry -> num_generic_parameters ;
2231+ inherited_iface_generic_param_index ++
2232+ ) {
2233+ const zend_generic_parameter * inherited_generic_parameter = & entry -> generic_parameters [inherited_iface_generic_param_index ];
2234+ const zend_type * iface_bound_type_ptr = zend_hash_index_find_ptr (interface_bound_types , inherited_iface_generic_param_index );
2235+ ZEND_ASSERT (iface_bound_type_ptr != NULL );
2236+ zend_type bound_type ;
2237+ if (ZEND_TYPE_IS_ASSOCIATED (* iface_bound_type_ptr )) {
2238+ memcpy (& bound_type , zend_hash_find_ptr (ce_bound_types , ZEND_TYPE_NAME (* iface_bound_type_ptr )), sizeof (zend_type ));
2239+ } else {
2240+ bound_type = * iface_bound_type_ptr ;
2241+ }
2242+ /* Deep type copy */
2243+ zend_type_copy_ctor (& bound_type , true, false);
2244+ zend_hash_add_mem (ce_bound_types_to_inherited_iface , inherited_generic_parameter -> name ,
2245+ & bound_type , sizeof (bound_type ));
2246+ }
2247+ zend_string_release_ex (inherited_iface_lc_name , false);
2248+ }
2249+ zend_string_release_ex (iface_lc_name , false);
2250+ }
2251+
22522252static void do_interface_implementation (zend_class_entry * ce , zend_class_entry * iface ) /* {{{ */
22532253{
22542254 zend_function * func ;
@@ -2334,6 +2334,9 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry *
23342334 zend_string_release (constraint_type_str );
23352335 return ;
23362336 }
2337+ ///* Bind our generic type (the key) to the generic iface type */
2338+ //zend_type iface_generic_type = (zend_type) ZEND_TYPE_INIT_CLASS(zend_string_copy(generic_parameter->name), /* allow null */ false, _ZEND_TYPE_ASSOCIATED_BIT);
2339+ //zend_hash_add_mem(bound_types, current_generic_param_name, &iface_generic_type, sizeof(iface_generic_type));
23372340 break ;
23382341 }
23392342 } else {
@@ -2361,7 +2364,7 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry *
23612364 }
23622365 }
23632366 }
2364- interface_bind_generic_types_for_interfaces (ce , iface );
2367+ bind_generic_types_for_inherited_interfaces (ce , iface );
23652368 ZEND_HASH_MAP_FOREACH_STR_KEY_PTR (& iface -> constants_table , key , c ) {
23662369 do_inherit_iface_constant (key , c , ce , iface );
23672370 } ZEND_HASH_FOREACH_END ();
0 commit comments