diff --git a/ChangeLog/6.0.11_dev.txt b/ChangeLog/6.0.11_dev.txt index ec3ce15c7c..ec63f531ee 100644 --- a/ChangeLog/6.0.11_dev.txt +++ b/ChangeLog/6.0.11_dev.txt @@ -1 +1,2 @@ -[postgresql] Dedicated exception when an extracting schema doesn't exist or it belongs to another user \ No newline at end of file +[postgresql] Dedicated exception when an extracting schema doesn't exist or it belongs to another user +[weaver] Fixed ctor processing with try...catch where there was broken catch section leaving diff --git a/Weaver/Xtensive.Orm.Weaver/Tasks/ImplementInitializablePatternTask.cs b/Weaver/Xtensive.Orm.Weaver/Tasks/ImplementInitializablePatternTask.cs index 9be4a2742c..0c09c43994 100644 --- a/Weaver/Xtensive.Orm.Weaver/Tasks/ImplementInitializablePatternTask.cs +++ b/Weaver/Xtensive.Orm.Weaver/Tasks/ImplementInitializablePatternTask.cs @@ -1,6 +1,6 @@ -// Copyright (C) 2013 Xtensive LLC. -// All rights reserved. -// For conditions of distribution and use, see license. +// Copyright (C) 2013-2022 Xtensive LLC. +// This code is distributed under MIT license terms. +// See the License.txt file in the project root for more information. // Created by: Denis Krjuchkov // Created: 2013.08.19 @@ -20,6 +20,7 @@ public override ActionResult Execute(ProcessorContext context) { var body = constructor.Body; var il = body.GetILProcessor(); + var originalLastRet = body.Instructions.Reverse().FirstOrDefault(i => i != null && i.OpCode.Code == Code.Ret); var leavePlaceholder = il.Create(OpCodes.Nop); var initializeCall = EmitInitializeCall(context, il); @@ -36,6 +37,12 @@ public override ActionResult Execute(ProcessorContext context) var ret = il.Create(OpCodes.Ret); il.Append(ret); il.Replace(leavePlaceholder, il.Create(OpCodes.Leave, ret)); + if (body.ExceptionHandlers.Count != 0) { + if (originalLastRet != null) + foreach (var eHandler in body.ExceptionHandlers) { + FixCatchLeave(eHandler.HandlerStart, eHandler.HandlerEnd, originalLastRet, initializeCall); + } + } body.InitLocals = true; var handler = new ExceptionHandler(ExceptionHandlerType.Catch) { @@ -61,6 +68,19 @@ private void ReplaceRetWithBr(ILProcessor il, Instruction start, Instruction end } } + private void FixCatchLeave(Instruction start, Instruction end, Instruction oldRetTarget, Instruction newTarget) + { + var current = start; + while (current != end && current != null) { + var next = current.Next; + var code = current.OpCode.Code; + if ((code == Code.Leave || code == Code.Leave_S) && current.Operand == oldRetTarget) { + current.Operand = newTarget; + } + current = next; + } + } + private Instruction GetStartInstruction(ILProcessor il) { var instructions = constructor.Body.Instructions;