@@ -6266,6 +6266,7 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
6266
6266
6267
6267
zend_class_entry * original_ce = CG (active_class_entry );
6268
6268
6269
+
6269
6270
if (EXPECTED ((decl -> flags & ZEND_ACC_ANON_CLASS ) == 0 )) {
6270
6271
zend_string * unqualified_name = decl -> name ;
6271
6272
@@ -6392,6 +6393,15 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
6392
6393
ce -> ce_flags |= ZEND_ACC_TOP_LEVEL ;
6393
6394
}
6394
6395
6396
+ // todo: add to set of classnames that need variance checks iff inheritance is involved
6397
+ if (extends_ast || implements_ast ) {
6398
+ if (CG (unverified_types )) {
6399
+ zend_hash_add_empty_element (CG (unverified_types ), lcname );
6400
+ } else {
6401
+ // todo: figure out why it's null; need a caller (somewhere) to initialize, emit, and destroy the unverified types
6402
+ }
6403
+ }
6404
+
6395
6405
if (toplevel
6396
6406
/* We currently don't early-bind classes that implement interfaces or use traits */
6397
6407
&& !(ce -> ce_flags & (ZEND_ACC_IMPLEMENT_INTERFACES |ZEND_ACC_IMPLEMENT_TRAITS ))) {
@@ -6471,8 +6481,6 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
6471
6481
opline -> opcode = ZEND_DECLARE_CLASS ;
6472
6482
}
6473
6483
}
6474
-
6475
- // todo: add to set of classnames that need variance checks iff inheritance is involved
6476
6484
}
6477
6485
/* }}} */
6478
6486
@@ -8076,6 +8084,35 @@ void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */
8076
8084
}
8077
8085
/* }}} */
8078
8086
8087
+ static zend_bool _is_type_decl (zend_ast * ast ) {
8088
+ return ast && ast -> kind == ZEND_AST_CLASS ;
8089
+ }
8090
+
8091
+ static zend_bool _is_not_decl_stmt (zend_ast * ast ) {
8092
+ if (ast ) {
8093
+ /* todo: what else should be considered a decl stmt? */
8094
+ switch (ast -> kind ) {
8095
+ case ZEND_AST_FUNC_DECL :
8096
+ case ZEND_AST_CLASS :
8097
+ return 0 ;
8098
+
8099
+ default :
8100
+ return 1 ;
8101
+ }
8102
+ }
8103
+
8104
+ /* todo: why are these sometimes null? */
8105
+ return 0 ;
8106
+ }
8107
+
8108
+ static zend_ast * * _ast_find (zend_ast * * begin , zend_ast * * end ,
8109
+ zend_bool (* pred )(zend_ast * )) {
8110
+ while (begin < end )
8111
+ if (pred (* begin ++ ))
8112
+ return begin ;
8113
+ return begin ;
8114
+ }
8115
+
8079
8116
/* Same as compile_stmt, but with early binding */
8080
8117
void zend_compile_top_stmt (zend_ast * ast ) /* {{{ */
8081
8118
{
@@ -8085,9 +8122,37 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
8085
8122
8086
8123
if (ast -> kind == ZEND_AST_STMT_LIST ) {
8087
8124
zend_ast_list * list = zend_ast_get_list (ast );
8088
- uint32_t i ;
8089
- for (i = 0 ; i < list -> children ; ++ i ) {
8090
- zend_compile_top_stmt (list -> child [i ]);
8125
+ zend_ast * * begin = list -> child ;
8126
+ zend_ast * * end = begin + list -> children ;
8127
+ zend_ast * * first_decl = _ast_find (begin , end , & _is_type_decl );
8128
+ zend_ast * * last_decl = _ast_find (first_decl , end , & _is_not_decl_stmt );
8129
+ zend_ast * * p ;
8130
+
8131
+ /* Compile opcodes before first type decl */
8132
+ for (p = begin ; p < first_decl ; ++ p ) {
8133
+ zend_compile_top_stmt (* p );
8134
+ }
8135
+
8136
+ /* Compile decl stmts */
8137
+ {
8138
+ HashTable unverified_types ;
8139
+ HashTable * prev_unverified_types ;
8140
+ zend_hash_init (& unverified_types , 0 , NULL , NULL , 1 );
8141
+ prev_unverified_types = CG (unverified_types );
8142
+ CG (unverified_types ) = & unverified_types ;
8143
+
8144
+ for (p = first_decl ; p < last_decl ; ++ p ) {
8145
+ zend_compile_top_stmt (* p );
8146
+ }
8147
+
8148
+ /* todo: emit ZEND_VERIFY_VARIANCE */
8149
+ zend_hash_destroy (& unverified_types );
8150
+ CG (unverified_types ) = prev_unverified_types ;
8151
+ }
8152
+
8153
+ /* Compile remainder */
8154
+ for (p = last_decl ; p < end ; ++ p ) {
8155
+ zend_compile_top_stmt (* p );
8091
8156
}
8092
8157
return ;
8093
8158
}
0 commit comments