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 .
4
4
// Created by: Denis Krjuchkov
5
5
// Created: 2013.08.19
6
6
@@ -20,6 +20,7 @@ public override ActionResult Execute(ProcessorContext context)
20
20
{
21
21
var body = constructor . Body ;
22
22
var il = body . GetILProcessor ( ) ;
23
+ var originalLastRet = body . Instructions . Reverse ( ) . FirstOrDefault ( i => i != null && i . OpCode . Code == Code . Ret ) ;
23
24
var leavePlaceholder = il . Create ( OpCodes . Nop ) ;
24
25
25
26
var initializeCall = EmitInitializeCall ( context , il ) ;
@@ -36,6 +37,12 @@ public override ActionResult Execute(ProcessorContext context)
36
37
var ret = il . Create ( OpCodes . Ret ) ;
37
38
il . Append ( ret ) ;
38
39
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
+ }
39
46
40
47
body . InitLocals = true ;
41
48
var handler = new ExceptionHandler ( ExceptionHandlerType . Catch ) {
@@ -61,6 +68,19 @@ private void ReplaceRetWithBr(ILProcessor il, Instruction start, Instruction end
61
68
}
62
69
}
63
70
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
+
64
84
private Instruction GetStartInstruction ( ILProcessor il )
65
85
{
66
86
var instructions = constructor . Body . Instructions ;
0 commit comments