@@ -6266,6 +6266,7 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
62666266
62676267 zend_class_entry * original_ce = CG (active_class_entry );
62686268
6269+
62696270 if (EXPECTED ((decl -> flags & ZEND_ACC_ANON_CLASS ) == 0 )) {
62706271 zend_string * unqualified_name = decl -> name ;
62716272
@@ -6392,6 +6393,15 @@ void zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
63926393 ce -> ce_flags |= ZEND_ACC_TOP_LEVEL ;
63936394 }
63946395
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+
63956405 if (toplevel
63966406 /* We currently don't early-bind classes that implement interfaces or use traits */
63976407 && !(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) /* {{{ */
64716481 opline -> opcode = ZEND_DECLARE_CLASS ;
64726482 }
64736483 }
6474-
6475- // todo: add to set of classnames that need variance checks iff inheritance is involved
64766484}
64776485/* }}} */
64786486
@@ -8076,6 +8084,35 @@ void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */
80768084}
80778085/* }}} */
80788086
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+
80798116/* Same as compile_stmt, but with early binding */
80808117void zend_compile_top_stmt (zend_ast * ast ) /* {{{ */
80818118{
@@ -8085,9 +8122,37 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
80858122
80868123 if (ast -> kind == ZEND_AST_STMT_LIST ) {
80878124 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 );
80918156 }
80928157 return ;
80938158 }
0 commit comments