@@ -1163,7 +1163,9 @@ ZEND_VM_C_LABEL(assign_dim_op_array):
1163
1163
SEPARATE_ARRAY (container );
1164
1164
ht = Z_ARRVAL_P (container );
1165
1165
ZEND_VM_C_LABEL (assign_dim_op_new_array ):
1166
- dim = GET_OP2_ZVAL_PTR_UNDEF (BP_VAR_R );
1166
+ dim = OP2_TYPE == IS_CONST && opline == & EG (delayed_error_op )[0 ]
1167
+ ? RT_CONSTANT (EG (opline_before_exception ), opline -> op2 )
1168
+ : GET_OP2_ZVAL_PTR_UNDEF (BP_VAR_R );
1167
1169
if (OP2_TYPE == IS_UNUSED ) {
1168
1170
var_ptr = zend_hash_next_index_insert (ht , & EG (uninitialized_zval ));
1169
1171
if (UNEXPECTED (!var_ptr )) {
@@ -1210,7 +1212,9 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
1210
1212
if (EXPECTED (Z_TYPE_P (container ) == IS_OBJECT )) {
1211
1213
zend_object * obj = Z_OBJ_P (container );
1212
1214
1213
- dim = GET_OP2_ZVAL_PTR_UNDEF (BP_VAR_R );
1215
+ dim = OP2_TYPE == IS_CONST && opline == & EG (delayed_error_op )[0 ]
1216
+ ? RT_CONSTANT (EG (opline_before_exception ), opline -> op2 )
1217
+ : GET_OP2_ZVAL_PTR_UNDEF (BP_VAR_R );
1214
1218
if (OP2_TYPE == IS_CONST && Z_EXTRA_P (dim ) == ZEND_EXTRA_VALUE ) {
1215
1219
dim ++ ;
1216
1220
}
@@ -1234,7 +1238,9 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
1234
1238
}
1235
1239
ZEND_VM_C_GOTO (assign_dim_op_new_array );
1236
1240
} else {
1237
- dim = GET_OP2_ZVAL_PTR (BP_VAR_R );
1241
+ dim = OP2_TYPE == IS_CONST && opline == & EG (delayed_error_op )[0 ]
1242
+ ? RT_CONSTANT (EG (opline_before_exception ), opline -> op2 )
1243
+ : GET_OP2_ZVAL_PTR_UNDEF (BP_VAR_R );
1238
1244
zend_binary_assign_op_dim_slow (container , dim OPLINE_CC EXECUTE_DATA_CC );
1239
1245
ZEND_VM_C_LABEL (assign_dim_op_ret_null ):
1240
1246
FREE_OP_DATA ();
@@ -8092,26 +8098,65 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
8092
8098
8093
8099
ZEND_VM_HANDLER (204 , ZEND_HANDLE_DELAYED_ERROR , ANY , ANY )
8094
8100
{
8095
- const zend_op * next_op = EG (opline_before_exception ) + 1 ;
8101
+ const zend_op * prev_op = EG (opline_before_exception );
8102
+ bool delay = false;
8103
+ switch (prev_op -> opcode ) {
8104
+ case ZEND_FETCH_W :
8105
+ case ZEND_FETCH_RW :
8106
+ case ZEND_FETCH_FUNC_ARG :
8107
+ case ZEND_FETCH_UNSET :
8108
+ case ZEND_FETCH_DIM_W :
8109
+ case ZEND_FETCH_DIM_RW :
8110
+ case ZEND_FETCH_DIM_UNSET :
8111
+ case ZEND_FETCH_LIST_W :
8112
+ case ZEND_FETCH_OBJ_W :
8113
+ case ZEND_FETCH_OBJ_RW :
8114
+ case ZEND_FETCH_OBJ_UNSET :
8115
+ delay = true;
8116
+ break ;
8117
+ }
8118
+
8119
+ // FIXME: Is this guaranteed to be there?
8120
+ const zend_op * next_op = prev_op + 1 ;
8096
8121
if (next_op -> opcode == ZEND_OP_DATA ) {
8097
8122
next_op ++ ;
8098
8123
}
8099
8124
8100
- /* Clear EG(delayed_errors), as more errors may be delayed while we are handling these. */
8101
- HashTable ht ;
8102
- memcpy (& ht , & EG (delayed_errors ), sizeof (HashTable ));
8103
- zend_hash_init (& EG (delayed_errors ), 0 , NULL , NULL , 0 );
8125
+ if (delay ) {
8126
+ EG (delayed_error_op )[0 ] = * next_op ;
8127
+ // FIXME: Is this guaranteed to be there?
8128
+ if (next_op [1 ].opcode == ZEND_OP_DATA ) {
8129
+ EG (delayed_error_op )[1 ] = next_op [1 ];
8130
+ } else {
8131
+ /* Reset to ZEND_HANDLE_DELAYED_ERROR */
8132
+ EG (delayed_error_op )[1 ] = EG (delayed_error_op )[2 ];
8133
+ }
8134
+ EG (opline_before_exception ) = next_op ;
8135
+ EG (current_execute_data )-> opline = EG (delayed_error_op );
8104
8136
8105
- zend_error_info * info ;
8106
- ZEND_HASH_FOREACH_PTR (& ht , info ) {
8107
- zend_error_zstr_at (info -> type , info -> filename , info -> lineno , info -> message );
8108
- zend_string_release (info -> filename );
8109
- zend_string_release (info -> message );
8110
- efree (info );
8111
- } ZEND_HASH_FOREACH_END ();
8112
- zend_hash_destroy (& ht );
8137
+ ZEND_VM_SET_NEXT_OPCODE (EG (delayed_error_op ));
8138
+ } else {
8139
+ /* Clear EG(delayed_errors), as more errors may be delayed while we are handling these. */
8140
+ HashTable ht ;
8141
+ memcpy (& ht , & EG (delayed_errors ), sizeof (HashTable ));
8142
+ zend_hash_init (& EG (delayed_errors ), 0 , NULL , NULL , 0 );
8143
+
8144
+ zend_error_info * info ;
8145
+ ZEND_HASH_FOREACH_PTR (& ht , info ) {
8146
+ zend_error_zstr_at (info -> type , info -> filename , info -> lineno , info -> message );
8147
+ zend_string_release (info -> filename );
8148
+ zend_string_release (info -> message );
8149
+ efree (info );
8150
+ } ZEND_HASH_FOREACH_END ();
8151
+ zend_hash_destroy (& ht );
8152
+
8153
+ if (EG (exception )) {
8154
+ HANDLE_EXCEPTION ();
8155
+ }
8156
+
8157
+ ZEND_VM_SET_NEXT_OPCODE (next_op );
8158
+ }
8113
8159
8114
- ZEND_VM_SET_NEXT_OPCODE (next_op );
8115
8160
ZEND_VM_CONTINUE ();
8116
8161
}
8117
8162
0 commit comments