зеркало из https://github.com/mono/ikvm-fork.git
Added non-standard API to disable the "helpful" automatic leave/endfinally instructions.
This commit is contained in:
Родитель
02bd9aed9e
Коммит
9605cfb009
|
@ -91,6 +91,7 @@ namespace IKVM.Reflection.Emit
|
||||||
private ushort maxStack;
|
private ushort maxStack;
|
||||||
private int stackHeight;
|
private int stackHeight;
|
||||||
private Scope scope;
|
private Scope scope;
|
||||||
|
private bool exceptionBlockAssistance = true;
|
||||||
|
|
||||||
private struct LabelFixup
|
private struct LabelFixup
|
||||||
{
|
{
|
||||||
|
@ -171,10 +172,19 @@ namespace IKVM.Reflection.Emit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// non-standard API
|
||||||
|
public void __DisableExceptionBlockAssistance()
|
||||||
|
{
|
||||||
|
exceptionBlockAssistance = false;
|
||||||
|
}
|
||||||
|
|
||||||
public void BeginCatchBlock(Type exceptionType)
|
public void BeginCatchBlock(Type exceptionType)
|
||||||
{
|
{
|
||||||
ExceptionBlock block = exceptionStack.Peek();
|
ExceptionBlock block = exceptionStack.Peek();
|
||||||
|
if (exceptionBlockAssistance)
|
||||||
|
{
|
||||||
Emit(OpCodes.Leave, block.labelEnd);
|
Emit(OpCodes.Leave, block.labelEnd);
|
||||||
|
}
|
||||||
stackHeight = 0;
|
stackHeight = 0;
|
||||||
UpdateStack(1);
|
UpdateStack(1);
|
||||||
if (block.tryLength == 0)
|
if (block.tryLength == 0)
|
||||||
|
@ -221,7 +231,10 @@ namespace IKVM.Reflection.Emit
|
||||||
public void BeginFinallyBlock()
|
public void BeginFinallyBlock()
|
||||||
{
|
{
|
||||||
ExceptionBlock block = exceptionStack.Peek();
|
ExceptionBlock block = exceptionStack.Peek();
|
||||||
|
if (exceptionBlockAssistance)
|
||||||
|
{
|
||||||
Emit(OpCodes.Leave, block.labelEnd);
|
Emit(OpCodes.Leave, block.labelEnd);
|
||||||
|
}
|
||||||
stackHeight = 0;
|
stackHeight = 0;
|
||||||
if (block.handlerOffset == 0)
|
if (block.handlerOffset == 0)
|
||||||
{
|
{
|
||||||
|
@ -230,9 +243,13 @@ namespace IKVM.Reflection.Emit
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
block.handlerLength = code.Position - block.handlerOffset;
|
block.handlerLength = code.Position - block.handlerOffset;
|
||||||
|
Label labelEnd = new Label();
|
||||||
|
if (exceptionBlockAssistance)
|
||||||
|
{
|
||||||
MarkLabel(block.labelEnd);
|
MarkLabel(block.labelEnd);
|
||||||
Label labelEnd = DefineLabel();
|
labelEnd = DefineLabel();
|
||||||
Emit(OpCodes.Leave, labelEnd);
|
Emit(OpCodes.Leave, labelEnd);
|
||||||
|
}
|
||||||
exceptionStack.Pop();
|
exceptionStack.Pop();
|
||||||
ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count);
|
ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count);
|
||||||
newBlock.labelEnd = labelEnd;
|
newBlock.labelEnd = labelEnd;
|
||||||
|
@ -248,6 +265,8 @@ namespace IKVM.Reflection.Emit
|
||||||
public void EndExceptionBlock()
|
public void EndExceptionBlock()
|
||||||
{
|
{
|
||||||
ExceptionBlock block = exceptionStack.Pop();
|
ExceptionBlock block = exceptionStack.Pop();
|
||||||
|
if (exceptionBlockAssistance)
|
||||||
|
{
|
||||||
if (block.exceptionType != null && block.exceptionType != FAULT)
|
if (block.exceptionType != null && block.exceptionType != FAULT)
|
||||||
{
|
{
|
||||||
Emit(OpCodes.Leave, block.labelEnd);
|
Emit(OpCodes.Leave, block.labelEnd);
|
||||||
|
@ -256,9 +275,10 @@ namespace IKVM.Reflection.Emit
|
||||||
{
|
{
|
||||||
Emit(OpCodes.Endfinally);
|
Emit(OpCodes.Endfinally);
|
||||||
}
|
}
|
||||||
block.handlerLength = code.Position - block.handlerOffset;
|
|
||||||
MarkLabel(block.labelEnd);
|
MarkLabel(block.labelEnd);
|
||||||
}
|
}
|
||||||
|
block.handlerLength = code.Position - block.handlerOffset;
|
||||||
|
}
|
||||||
|
|
||||||
public void BeginScope()
|
public void BeginScope()
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче