@@ -9094,10 +9094,9 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */
90949094}
90959095/* }}} */
90969096
9097- static void zend_compile_implements (zend_ast * ast ) /* {{{ */
9097+ static void zend_compile_implements (zend_ast * ast , zend_class_entry * ce ) /* {{{ */
90989098{
90999099 zend_ast_list * list = zend_ast_get_list (ast );
9100- zend_class_entry * ce = CG (active_class_entry );
91019100 zend_class_name * interface_names ;
91029101 uint32_t i ;
91039102
@@ -9155,6 +9154,17 @@ static void zend_compile_enum_backing_type(zend_class_entry *ce, zend_ast *enum_
91559154 zend_type_release (type , 0 );
91569155}
91579156
9157+ HashTable * inner_class_queue = NULL ;
9158+
9159+ static void zend_defer_class_decl (zend_ast * ast ) {
9160+ if (inner_class_queue == NULL ) {
9161+ ALLOC_HASHTABLE (inner_class_queue );
9162+ zend_hash_init (inner_class_queue , 8 , NULL , ZVAL_PTR_DTOR , 0 );
9163+ }
9164+
9165+ zend_hash_next_index_insert_ptr (inner_class_queue , ast );
9166+ }
9167+
91589168static void zend_compile_class_decl (znode * result , zend_ast * ast , bool toplevel ) /* {{{ */
91599169{
91609170 zend_ast_decl * decl = (zend_ast_decl * ) ast ;
@@ -9285,16 +9295,16 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
92859295 zend_resolve_const_class_name_reference (extends_ast , "class name" );
92869296 }
92879297
9298+ if (implements_ast ) {
9299+ zend_compile_implements (implements_ast , ce );
9300+ }
9301+
92889302 CG (active_class_entry ) = ce ;
92899303
92909304 if (decl -> child [3 ]) {
92919305 zend_compile_attributes (& ce -> attributes , decl -> child [3 ], 0 , ZEND_ATTRIBUTE_TARGET_CLASS , 0 );
92929306 }
92939307
9294- if (implements_ast ) {
9295- zend_compile_implements (implements_ast );
9296- }
9297-
92989308 if (ce -> ce_flags & ZEND_ACC_ENUM ) {
92999309 if (enum_backing_type_ast != NULL ) {
93009310 zend_compile_enum_backing_type (ce , enum_backing_type_ast );
@@ -9312,8 +9322,6 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
93129322 zend_verify_abstract_class (ce );
93139323 }
93149324
9315- CG (active_class_entry ) = original_ce ;
9316-
93179325 if (toplevel ) {
93189326 ce -> ce_flags |= ZEND_ACC_TOP_LEVEL ;
93199327 }
@@ -9334,7 +9342,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
93349342 && !zend_compile_ignore_class (parent_ce , ce -> info .user .filename )) {
93359343 if (zend_try_early_bind (ce , parent_ce , lcname , NULL )) {
93369344 zend_string_release (lcname );
9337- return ;
9345+ goto compile_inner_classes ;
93389346 }
93399347 }
93409348 } else if (EXPECTED (zend_hash_add_ptr (CG (class_table ), lcname , ce ) != NULL )) {
@@ -9343,7 +9351,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
93439351 zend_inheritance_check_override (ce );
93449352 ce -> ce_flags |= ZEND_ACC_LINKED ;
93459353 zend_observer_class_linked_notify (ce , lcname );
9346- return ;
9354+ goto compile_inner_classes ;
93479355 } else {
93489356 goto link_unbound ;
93499357 }
@@ -9413,6 +9421,24 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
94139421 opline -> result .opline_num = -1 ;
94149422 }
94159423 }
9424+ compile_inner_classes :
9425+
9426+ if (inner_class_queue == NULL ) {
9427+ CG (active_class_entry ) = original_ce ;
9428+ return ;
9429+ }
9430+
9431+ HashTable * queue = inner_class_queue ;
9432+ inner_class_queue = NULL ;
9433+
9434+ ZEND_HASH_FOREACH_PTR (queue , ast ) {
9435+ zend_compile_class_decl (NULL , ast , 0 );
9436+ } ZEND_HASH_FOREACH_END ();
9437+
9438+ CG (active_class_entry ) = original_ce ;
9439+
9440+ zend_hash_destroy (queue );
9441+ FREE_HASHTABLE (queue );
94169442}
94179443/* }}} */
94189444
@@ -11692,6 +11718,10 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
1169211718 zend_compile_use (ast );
1169311719 break ;
1169411720 case ZEND_AST_CONST_DECL :
11721+ if (CG (active_class_entry )) {
11722+ zend_defer_class_decl (ast );
11723+ break ;
11724+ }
1169511725 zend_compile_const_decl (ast );
1169611726 break ;
1169711727 case ZEND_AST_NAMESPACE :
0 commit comments