@@ -2073,6 +2073,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, bool nullify_hand
20732073 ce -> properties_info_table = NULL ;
20742074 ce -> attributes = NULL ;
20752075 ce -> associated_types = NULL ;
2076+ ce -> num_associated_types = 0 ;
20762077 ce -> enum_backing_type = IS_UNDEF ;
20772078 ce -> backed_enum_table = NULL ;
20782079
@@ -7005,8 +7006,14 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
70057006 if (fetch_type == ZEND_FETCH_CLASS_DEFAULT ) {
70067007 class_name = zend_resolve_class_name_ast (ast );
70077008 zend_assert_valid_class_name (class_name , "a type name" );
7008- if (ce && ce -> associated_types && zend_hash_exists (ce -> associated_types , class_name )) {
7009- flags = _ZEND_TYPE_ASSOCIATED_BIT ;
7009+ if (ce && ce -> associated_types ) {
7010+ for (uint32_t i = 0 ; i < ce -> num_associated_types ; i ++ ) {
7011+ const zend_string * cur = ce -> associated_types [i ];
7012+ if (zend_string_equals (class_name , cur )) {
7013+ flags = _ZEND_TYPE_ASSOCIATED_BIT ;
7014+ break ;
7015+ }
7016+ }
70107017 }
70117018 } else {
70127019 ZEND_ASSERT (fetch_type == ZEND_FETCH_CLASS_SELF || fetch_type == ZEND_FETCH_CLASS_PARENT );
@@ -9035,9 +9042,9 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */
90359042
90369043
90379044
9038- static void zend_compile_associated_type (zend_ast * ast ) {
9045+ static void zend_compile_associated_type (const zend_ast * ast ) {
90399046 zend_class_entry * ce = CG (active_class_entry );
9040- HashTable * associated_types = ce -> associated_types ;
9047+ zend_string * * associated_types = ce -> associated_types ;
90419048 zend_ast * name_ast = ast -> child [0 ];
90429049 zend_string * name = zend_ast_get_str (name_ast );
90439050
@@ -9047,19 +9054,26 @@ static void zend_compile_associated_type(zend_ast *ast) {
90479054 }
90489055
90499056 ZEND_ASSERT (name != NULL );
9050- bool persistent = false; // TODO I need to figure this out
9057+ // TODO This is very jank
9058+ const bool persistent = ce -> type == ZEND_INTERNAL_CLASS ;
90519059 if (associated_types == NULL ) {
9052- ce -> associated_types = pemalloc (sizeof (HashTable ), persistent );
9053- zend_hash_init (ce -> associated_types , 8 , NULL , NULL , persistent );
9054- associated_types = ce -> associated_types ;
9060+ ce -> associated_types = pemalloc (sizeof (zend_string * ), persistent );
9061+ ce -> associated_types [0 ] = zend_string_copy (name );
9062+ ce -> num_associated_types = 1 ;
9063+ return ;
90559064 }
9056- if (zend_hash_exists (associated_types , name )) {
9057- zend_error_noreturn (E_COMPILE_ERROR ,
9058- "Cannot have two associated types with the same name \"%s\"" , ZSTR_VAL (name ));
9065+ for (uint32_t i = 0 ; i < ce -> num_associated_types ; i ++ ) {
9066+ const zend_string * cur = ce -> associated_types [i ];
9067+ if (zend_string_equals (name , cur )) {
9068+ zend_error_noreturn (E_COMPILE_ERROR ,
9069+ "Cannot have two associated types with the same name \"%s\"" , ZSTR_VAL (name ));
9070+ return ;
9071+ }
90599072 }
9060- zval tmp ;
9061- ZVAL_UNDEF (& tmp );
9062- zend_hash_add_new (associated_types , name , & tmp );
9073+ uint32_t new_size = ce -> num_associated_types + 1 ;
9074+ ce -> associated_types = perealloc (ce -> associated_types , new_size * sizeof (zend_string * ), persistent );
9075+ ce -> associated_types [ce -> num_associated_types ] = zend_string_copy (name );
9076+ ce -> num_associated_types = new_size ;
90639077}
90649078
90659079static void zend_compile_implements (zend_ast * ast ) /* {{{ */
0 commit comments