@@ -9094,10 +9094,9 @@ static void zend_compile_use_trait(zend_ast *ast) /* {{{ */
9094
9094
}
9095
9095
/* }}} */
9096
9096
9097
- static void zend_compile_implements (zend_ast * ast ) /* {{{ */
9097
+ static void zend_compile_implements (zend_ast * ast , zend_class_entry * ce ) /* {{{ */
9098
9098
{
9099
9099
zend_ast_list * list = zend_ast_get_list (ast );
9100
- zend_class_entry * ce = CG (active_class_entry );
9101
9100
zend_class_name * interface_names ;
9102
9101
uint32_t i ;
9103
9102
@@ -9155,6 +9154,17 @@ static void zend_compile_enum_backing_type(zend_class_entry *ce, zend_ast *enum_
9155
9154
zend_type_release (type , 0 );
9156
9155
}
9157
9156
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
+
9158
9168
static void zend_compile_class_decl (znode * result , zend_ast * ast , bool toplevel ) /* {{{ */
9159
9169
{
9160
9170
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)
9285
9295
zend_resolve_const_class_name_reference (extends_ast , "class name" );
9286
9296
}
9287
9297
9298
+ if (implements_ast ) {
9299
+ zend_compile_implements (implements_ast , ce );
9300
+ }
9301
+
9288
9302
CG (active_class_entry ) = ce ;
9289
9303
9290
9304
if (decl -> child [3 ]) {
9291
9305
zend_compile_attributes (& ce -> attributes , decl -> child [3 ], 0 , ZEND_ATTRIBUTE_TARGET_CLASS , 0 );
9292
9306
}
9293
9307
9294
- if (implements_ast ) {
9295
- zend_compile_implements (implements_ast );
9296
- }
9297
-
9298
9308
if (ce -> ce_flags & ZEND_ACC_ENUM ) {
9299
9309
if (enum_backing_type_ast != NULL ) {
9300
9310
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)
9312
9322
zend_verify_abstract_class (ce );
9313
9323
}
9314
9324
9315
- CG (active_class_entry ) = original_ce ;
9316
-
9317
9325
if (toplevel ) {
9318
9326
ce -> ce_flags |= ZEND_ACC_TOP_LEVEL ;
9319
9327
}
@@ -9334,7 +9342,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
9334
9342
&& !zend_compile_ignore_class (parent_ce , ce -> info .user .filename )) {
9335
9343
if (zend_try_early_bind (ce , parent_ce , lcname , NULL )) {
9336
9344
zend_string_release (lcname );
9337
- return ;
9345
+ goto compile_inner_classes ;
9338
9346
}
9339
9347
}
9340
9348
} 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)
9343
9351
zend_inheritance_check_override (ce );
9344
9352
ce -> ce_flags |= ZEND_ACC_LINKED ;
9345
9353
zend_observer_class_linked_notify (ce , lcname );
9346
- return ;
9354
+ goto compile_inner_classes ;
9347
9355
} else {
9348
9356
goto link_unbound ;
9349
9357
}
@@ -9413,6 +9421,24 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
9413
9421
opline -> result .opline_num = -1 ;
9414
9422
}
9415
9423
}
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 );
9416
9442
}
9417
9443
/* }}} */
9418
9444
@@ -11692,6 +11718,10 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
11692
11718
zend_compile_use (ast );
11693
11719
break ;
11694
11720
case ZEND_AST_CONST_DECL :
11721
+ if (CG (active_class_entry )) {
11722
+ zend_defer_class_decl (ast );
11723
+ break ;
11724
+ }
11695
11725
zend_compile_const_decl (ast );
11696
11726
break ;
11697
11727
case ZEND_AST_NAMESPACE :
0 commit comments