1- // Copyright (C) 2013 Xtensive LLC.
2- // All rights reserved .
3- // For conditions of distribution and use, see license .
1+ // Copyright (C) 2013-2022 Xtensive LLC.
2+ // This code is distributed under MIT license terms .
3+ // See the License.txt file in the project root for more information .
44// Created by: Denis Krjuchkov
55// Created: 2013.08.19
66
@@ -20,6 +20,7 @@ public override ActionResult Execute(ProcessorContext context)
2020 {
2121 var body = constructor . Body ;
2222 var il = body . GetILProcessor ( ) ;
23+ var originalLastRet = body . Instructions . Reverse ( ) . FirstOrDefault ( i => i != null && i . OpCode . Code == Code . Ret ) ;
2324 var leavePlaceholder = il . Create ( OpCodes . Nop ) ;
2425
2526 var initializeCall = EmitInitializeCall ( context , il ) ;
@@ -36,6 +37,12 @@ public override ActionResult Execute(ProcessorContext context)
3637 var ret = il . Create ( OpCodes . Ret ) ;
3738 il . Append ( ret ) ;
3839 il . Replace ( leavePlaceholder , il . Create ( OpCodes . Leave , ret ) ) ;
40+ if ( body . ExceptionHandlers . Count != 0 ) {
41+ if ( originalLastRet != null )
42+ foreach ( var eHandler in body . ExceptionHandlers ) {
43+ FixCatchLeave ( eHandler . HandlerStart , eHandler . HandlerEnd , originalLastRet , initializeCall ) ;
44+ }
45+ }
3946
4047 body . InitLocals = true ;
4148 var handler = new ExceptionHandler ( ExceptionHandlerType . Catch ) {
@@ -61,6 +68,19 @@ private void ReplaceRetWithBr(ILProcessor il, Instruction start, Instruction end
6168 }
6269 }
6370
71+ private void FixCatchLeave ( Instruction start , Instruction end , Instruction oldRetTarget , Instruction newTarget )
72+ {
73+ var current = start ;
74+ while ( current != end && current != null ) {
75+ var next = current . Next ;
76+ var code = current . OpCode . Code ;
77+ if ( ( code == Code . Leave || code == Code . Leave_S ) && current . Operand == oldRetTarget ) {
78+ current . Operand = newTarget ;
79+ }
80+ current = next ;
81+ }
82+ }
83+
6484 private Instruction GetStartInstruction ( ILProcessor il )
6585 {
6686 var instructions = constructor . Body . Instructions ;
0 commit comments