@@ -6108,14 +6108,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
6108
6108
ptrdiff_t target = next_ip - td -> il_code + offset ;
6109
6109
InterpBasicBlock * target_bb = td -> offset_to_bb [target ];
6110
6110
g_assert (target_bb );
6111
- if (offset < 0 ) {
6112
- #if DEBUG_INTERP
6113
- if (stack_height > 0 && stack_height != target_bb -> stack_height )
6114
- g_warning ("SWITCH with back branch and non-empty stack" );
6115
- #endif
6116
- } else {
6117
- init_bb_stack_state (td , target_bb );
6118
- }
6111
+ init_bb_stack_state (td , target_bb );
6119
6112
target_bb_table [i ] = target_bb ;
6120
6113
interp_link_bblocks (td , td -> cbb , target_bb );
6121
6114
td -> ip += 4 ;
@@ -8774,6 +8767,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
8774
8767
if (next_bb -> emit_state == BB_STATE_NOT_EMITTED && next_bb != exit_bb ) {
8775
8768
if (td -> verbose_level )
8776
8769
g_print ("Unlink BB%d\n" , next_bb -> index );
8770
+ td -> offset_to_bb [next_bb -> il_offset ] = NULL ;
8777
8771
prev_bb -> next_bb = next_bb -> next_bb ;
8778
8772
next_bb = prev_bb -> next_bb ;
8779
8773
} else {
@@ -9519,20 +9513,35 @@ interp_squash_initlocals (TransformData *td)
9519
9513
}
9520
9514
}
9521
9515
9516
+ // If precise is true, il_offset should point to the offset of a bblock
9517
+ // If precise is false, il_offset points to the end of a block, so we just
9518
+ // return the native offset of the first live bblock that we can find after it
9522
9519
static int
9523
- get_native_offset (TransformData * td , int il_offset )
9520
+ get_native_offset (TransformData * td , int il_offset , gboolean precise )
9524
9521
{
9525
- // We can't access offset_to_bb for header->code_size IL offset. Also, offset_to_bb
9526
- // is not set for dead bblocks at method end.
9527
- if (GINT_TO_UINT32 (il_offset ) < td -> header -> code_size && td -> offset_to_bb [il_offset ]) {
9522
+ if (GINT_TO_UINT32 (il_offset ) < td -> header -> code_size ) {
9528
9523
InterpBasicBlock * bb = td -> offset_to_bb [il_offset ];
9529
- g_assert (!bb -> dead );
9530
- return bb -> native_offset ;
9531
- } else {
9532
- return GPTRDIFF_TO_INT (td -> new_code_end - td -> new_code );
9524
+ if (bb ) {
9525
+ g_assert (!bb -> dead );
9526
+ return bb -> native_offset ;
9527
+ } else {
9528
+ if (precise )
9529
+ return -1 ;
9530
+ while (GINT_TO_UINT32 (il_offset ) < td -> header -> code_size ) {
9531
+ bb = td -> offset_to_bb [il_offset ];
9532
+ if (bb ) {
9533
+ g_assert (!bb -> dead );
9534
+ return bb -> native_offset ;
9535
+ }
9536
+ il_offset ++ ;
9537
+ }
9538
+ }
9533
9539
}
9540
+ return GPTRDIFF_TO_INT (td -> new_code_end - td -> new_code );
9534
9541
}
9535
9542
9543
+ void mono_break (void );
9544
+
9536
9545
static void
9537
9546
generate (MonoMethod * method , MonoMethodHeader * header , InterpMethod * rtm , MonoGenericContext * generic_context , MonoError * error )
9538
9547
{
@@ -9702,15 +9711,25 @@ generate (MonoMethod *method, MonoMethodHeader *header, InterpMethod *rtm, MonoG
9702
9711
for (guint i = 0 ; i < header -> num_clauses ; i ++ ) {
9703
9712
MonoExceptionClause * c = rtm -> clauses + i ;
9704
9713
int end_off = c -> try_offset + c -> try_len ;
9705
- c -> try_offset = get_native_offset (td , c -> try_offset );
9706
- c -> try_len = get_native_offset (td , end_off ) - c -> try_offset ;
9714
+ if (td -> verbose_level )
9715
+ mono_break ();
9716
+ int try_native_offset = get_native_offset (td , c -> try_offset , TRUE);
9717
+ // Try block could have been unreachable code, skip clause
9718
+ if (try_native_offset == -1 ) {
9719
+ // reset try range so nothing is protected
9720
+ c -> try_offset = code_len_u16 ;
9721
+ c -> try_len = 0 ;
9722
+ continue ;
9723
+ }
9724
+ c -> try_offset = try_native_offset ;
9725
+ c -> try_len = get_native_offset (td , end_off , FALSE) - c -> try_offset ;
9707
9726
g_assert ((c -> try_offset + c -> try_len ) <= code_len_u16 );
9708
9727
end_off = c -> handler_offset + c -> handler_len ;
9709
- c -> handler_offset = get_native_offset (td , c -> handler_offset );
9710
- c -> handler_len = get_native_offset (td , end_off ) - c -> handler_offset ;
9728
+ c -> handler_offset = get_native_offset (td , c -> handler_offset , TRUE );
9729
+ c -> handler_len = get_native_offset (td , end_off , FALSE ) - c -> handler_offset ;
9711
9730
g_assert (c -> handler_len >= 0 && (c -> handler_offset + c -> handler_len ) <= code_len_u16 );
9712
9731
if (c -> flags & MONO_EXCEPTION_CLAUSE_FILTER )
9713
- c -> data .filter_offset = get_native_offset (td , c -> data .filter_offset );
9732
+ c -> data .filter_offset = get_native_offset (td , c -> data .filter_offset , TRUE );
9714
9733
}
9715
9734
// When optimized (using the var offset allocator), total_locals_size contains also the param area.
9716
9735
// When unoptimized, the param area is stored in the same order, within the IL execution stack.
0 commit comments