@@ -4114,6 +4114,27 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{
4114
4114
}
4115
4115
/* }}} */
4116
4116
4117
+
4118
+ static
4119
+ void _backup_unverified_variance_types (HashTable * unverified_types ,
4120
+ HashTable * * prev_unverified_types )
4121
+ {
4122
+ zend_hash_init (unverified_types , 0 , NULL , NULL , 1 );
4123
+ * prev_unverified_types = CG (unverified_types );
4124
+ CG (unverified_types ) = unverified_types ;
4125
+ }
4126
+
4127
+ static void _compile_verify_variance (HashTable * unverified_types )
4128
+ {
4129
+ zend_string * lcname ;
4130
+ ZEND_HASH_FOREACH_STR_KEY (unverified_types , lcname ) {
4131
+ zend_op * opline = get_next_op ();
4132
+ opline -> op1_type = IS_CONST ;
4133
+ opline -> opcode = ZEND_VERIFY_VARIANCE ;
4134
+ LITERAL_STR (opline -> op1 , lcname );
4135
+ } ZEND_HASH_FOREACH_END ();
4136
+ }
4137
+
4117
4138
void zend_compile_class_decl (zend_ast * ast , zend_bool toplevel );
4118
4139
4119
4140
void zend_compile_new (znode * result , zend_ast * ast ) /* {{{ */
@@ -4125,16 +4146,29 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
4125
4146
zend_op * opline ;
4126
4147
4127
4148
if (class_ast -> kind == ZEND_AST_CLASS ) {
4128
- uint32_t dcl_opnum = get_next_op_number ();
4129
- zend_compile_class_decl (class_ast , 0 );
4130
- /* jump over anon class declaration */
4131
- opline = & CG (active_op_array )-> opcodes [dcl_opnum ];
4132
- if (opline -> opcode == ZEND_FETCH_CLASS ) {
4133
- opline ++ ;
4134
- }
4135
- class_node .op_type = opline -> result_type ;
4136
- class_node .u .op .var = opline -> result .var ;
4137
- opline -> extended_value = get_next_op_number ();
4149
+ /* backup previous unverified variance list; anon classes are immediately verified */
4150
+ HashTable unverified_types ;
4151
+ HashTable * prev_unverified_types ;
4152
+ _backup_unverified_variance_types (& unverified_types , & prev_unverified_types );
4153
+
4154
+ {
4155
+ uint32_t dcl_opnum = get_next_op_number ();
4156
+ zend_compile_class_decl (class_ast , 0 );
4157
+ /* jump over anon class declaration */
4158
+ opline = & CG (active_op_array )-> opcodes [dcl_opnum ];
4159
+ if (opline -> opcode == ZEND_FETCH_CLASS ) {
4160
+ opline ++ ;
4161
+ }
4162
+ class_node .op_type = opline -> result_type ;
4163
+ class_node .u .op .var = opline -> result .var ;
4164
+ opline -> extended_value = get_next_op_number ();
4165
+ }
4166
+
4167
+ _compile_verify_variance (& unverified_types );
4168
+
4169
+ zend_hash_destroy (& unverified_types );
4170
+ CG (unverified_types ) = prev_unverified_types ;
4171
+
4138
4172
} else {
4139
4173
zend_compile_class_ref_ex (& class_node , class_ast , ZEND_FETCH_CLASS_EXCEPTION );
4140
4174
}
@@ -8135,26 +8169,15 @@ void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
8135
8169
8136
8170
/* Compile decl stmts */
8137
8171
{
8138
- zend_string * lcname ;
8139
8172
HashTable unverified_types ;
8140
8173
HashTable * prev_unverified_types ;
8141
- zend_hash_init (& unverified_types , 0 , NULL , NULL , 1 );
8142
- prev_unverified_types = CG (unverified_types );
8143
- CG (unverified_types ) = & unverified_types ;
8174
+ _backup_unverified_variance_types (& unverified_types , & prev_unverified_types );
8144
8175
8145
8176
for (p = first_decl ; p < last_decl ; ++ p ) {
8146
8177
zend_compile_top_stmt (* p );
8147
8178
}
8148
8179
8149
- /* todo: emit ZEND_VERIFY_VARIANCE */
8150
- ZEND_HASH_FOREACH_STR_KEY (& unverified_types , lcname ) {
8151
- zend_op * opline = get_next_op (CG (active_op_array ));
8152
-
8153
- opline -> op1_type = IS_CONST ;
8154
- opline -> opcode = ZEND_VERIFY_VARIANCE ;
8155
- LITERAL_STR (opline -> op1 , lcname );
8156
-
8157
- } ZEND_HASH_FOREACH_END ();
8180
+ _compile_verify_variance (& unverified_types );
8158
8181
8159
8182
zend_hash_destroy (& unverified_types );
8160
8183
CG (unverified_types ) = prev_unverified_types ;
0 commit comments