Patcher correctly translates catch clauses
This commit is contained in:
@@ -12,19 +12,9 @@ namespace Torch.Managers.PatchManager.MSIL
|
||||
/// </summary>
|
||||
public enum MsilTryCatchOperationType
|
||||
{
|
||||
// TryCatchBlockIL:
|
||||
// var exBlock = ILGenerator.BeginExceptionBlock();
|
||||
// try{
|
||||
// ILGenerator.BeginCatchBlock(typeof(Exception));
|
||||
// } catch(Exception e) {
|
||||
// ILGenerator.BeginCatchBlock(null);
|
||||
// } catch {
|
||||
// ILGenerator.BeginFinallyBlock();
|
||||
// }finally {
|
||||
// ILGenerator.EndExceptionBlock();
|
||||
// }
|
||||
BeginExceptionBlock,
|
||||
BeginCatchBlock,
|
||||
BeginClauseBlock,
|
||||
BeginFaultBlock,
|
||||
BeginFinallyBlock,
|
||||
EndExceptionBlock
|
||||
}
|
||||
@@ -46,9 +36,11 @@ namespace Torch.Managers.PatchManager.MSIL
|
||||
public MsilTryCatchOperation(MsilTryCatchOperationType op, Type caughtType = null)
|
||||
{
|
||||
Type = op;
|
||||
if (caughtType != null && op != MsilTryCatchOperationType.BeginCatchBlock)
|
||||
if (caughtType != null && op != MsilTryCatchOperationType.BeginClauseBlock)
|
||||
throw new ArgumentException($"Can't use caught type with operation type {op}", nameof(caughtType));
|
||||
CatchType = caughtType;
|
||||
}
|
||||
|
||||
public override string ToString() => $"{Type} -> {CatchType}";
|
||||
}
|
||||
}
|
||||
|
@@ -43,10 +43,8 @@ namespace Torch.Managers.PatchManager.Transpile
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma warning disable 649
|
||||
[ReflectedMethod(Name = "BakeByteArray")]
|
||||
private static Func<ILGenerator, byte[]> _ilGeneratorBakeByteArray;
|
||||
[ReflectedMethod(Name = "BakeByteArray")] private static Func<ILGenerator, byte[]> _ilGeneratorBakeByteArray;
|
||||
#pragma warning restore 649
|
||||
|
||||
public MethodContext(DynamicMethod method)
|
||||
@@ -86,7 +84,8 @@ namespace Torch.Managers.PatchManager.Transpile
|
||||
continue;
|
||||
}
|
||||
if (opcode.Size != memory.Position - opcodeOffset)
|
||||
throw new Exception($"Opcode said it was {opcode.Size} but we read {memory.Position - opcodeOffset}");
|
||||
throw new Exception(
|
||||
$"Opcode said it was {opcode.Size} but we read {memory.Position - opcodeOffset}");
|
||||
var instruction = new MsilInstruction(opcode)
|
||||
{
|
||||
Offset = opcodeOffset
|
||||
@@ -105,16 +104,24 @@ namespace Torch.Managers.PatchManager.Transpile
|
||||
var beginInstruction = FindInstruction(clause.TryOffset);
|
||||
var catchInstruction = FindInstruction(clause.HandlerOffset);
|
||||
var finalInstruction = FindInstruction(clause.HandlerOffset + clause.HandlerLength);
|
||||
beginInstruction.TryCatchOperation = new MsilTryCatchOperation(MsilTryCatchOperationType.BeginExceptionBlock);
|
||||
if ((clause.Flags & ExceptionHandlingClauseOptions.Clause) != 0)
|
||||
catchInstruction.TryCatchOperation = new MsilTryCatchOperation(MsilTryCatchOperationType.BeginCatchBlock, clause.CatchType);
|
||||
beginInstruction.TryCatchOperation =
|
||||
new MsilTryCatchOperation(MsilTryCatchOperationType.BeginExceptionBlock);
|
||||
if ((clause.Flags & ExceptionHandlingClauseOptions.Fault) != 0)
|
||||
catchInstruction.TryCatchOperation =
|
||||
new MsilTryCatchOperation(MsilTryCatchOperationType.BeginFaultBlock);
|
||||
else if ((clause.Flags & ExceptionHandlingClauseOptions.Finally) != 0)
|
||||
catchInstruction.TryCatchOperation = new MsilTryCatchOperation(MsilTryCatchOperationType.BeginFinallyBlock);
|
||||
finalInstruction.TryCatchOperation = new MsilTryCatchOperation(MsilTryCatchOperationType.EndExceptionBlock);
|
||||
catchInstruction.TryCatchOperation =
|
||||
new MsilTryCatchOperation(MsilTryCatchOperationType.BeginFinallyBlock);
|
||||
else
|
||||
catchInstruction.TryCatchOperation =
|
||||
new MsilTryCatchOperation(MsilTryCatchOperationType.BeginClauseBlock, clause.CatchType);
|
||||
|
||||
finalInstruction.TryCatchOperation =
|
||||
new MsilTryCatchOperation(MsilTryCatchOperationType.EndExceptionBlock);
|
||||
}
|
||||
}
|
||||
|
||||
private MsilInstruction FindInstruction(int offset)
|
||||
public MsilInstruction FindInstruction(int offset)
|
||||
{
|
||||
int min = 0, max = _instructions.Count;
|
||||
while (min != max)
|
||||
|
@@ -60,9 +60,12 @@ namespace Torch.Managers.PatchManager.Transpile
|
||||
case MsilTryCatchOperationType.BeginExceptionBlock:
|
||||
target.BeginExceptionBlock();
|
||||
break;
|
||||
case MsilTryCatchOperationType.BeginCatchBlock:
|
||||
case MsilTryCatchOperationType.BeginClauseBlock:
|
||||
target.BeginCatchBlock(il.TryCatchOperation.CatchType);
|
||||
break;
|
||||
case MsilTryCatchOperationType.BeginFaultBlock:
|
||||
target.BeginFaultBlock();
|
||||
break;
|
||||
case MsilTryCatchOperationType.BeginFinallyBlock:
|
||||
target.BeginFinallyBlock();
|
||||
break;
|
||||
@@ -80,11 +83,12 @@ namespace Torch.Managers.PatchManager.Transpile
|
||||
|
||||
// Leave opcodes emitted by these:
|
||||
if (il.OpCode == OpCodes.Endfilter && ilNext?.TryCatchOperation?.Type ==
|
||||
MsilTryCatchOperationType.BeginCatchBlock)
|
||||
MsilTryCatchOperationType.BeginClauseBlock)
|
||||
continue;
|
||||
if ((il.OpCode == OpCodes.Leave || il.OpCode == OpCodes.Leave_S) &&
|
||||
(ilNext?.TryCatchOperation?.Type == MsilTryCatchOperationType.EndExceptionBlock ||
|
||||
ilNext?.TryCatchOperation?.Type == MsilTryCatchOperationType.BeginCatchBlock ||
|
||||
ilNext?.TryCatchOperation?.Type == MsilTryCatchOperationType.BeginClauseBlock ||
|
||||
ilNext?.TryCatchOperation?.Type == MsilTryCatchOperationType.BeginFaultBlock ||
|
||||
ilNext?.TryCatchOperation?.Type == MsilTryCatchOperationType.BeginFinallyBlock))
|
||||
continue;
|
||||
if ((il.OpCode == OpCodes.Leave || il.OpCode == OpCodes.Leave_S || il.OpCode == OpCodes.Endfinally) &&
|
||||
@@ -175,7 +179,7 @@ namespace Torch.Managers.PatchManager.Transpile
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (k.OpCode == OpCodes.Br || k.OpCode == OpCodes.Br_S)
|
||||
if (k.OpCode == OpCodes.Br || k.OpCode == OpCodes.Br_S || k.OpCode == OpCodes.Leave || k.OpCode == OpCodes.Leave_S)
|
||||
unreachable = true;
|
||||
}
|
||||
foreach (var k in data)
|
||||
|
Reference in New Issue
Block a user