本文整理汇总了C#中Jurassic.Compiler.ILGenerator.Leave方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.Leave方法的具体用法?C# ILGenerator.Leave怎么用?C# ILGenerator.Leave使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.Leave方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: GenerateCode
//.........这里部分代码省略.........
if (this.FinallyBlock != null)
generator.BeginExceptionBlock();
// Begin the exception block.
generator.BeginExceptionBlock();
// Generate code for the try block.
this.TryBlock.GenerateCode(generator, optimizationInfo);
// Generate code for the catch block.
if (this.CatchBlock != null)
{
// Begin a catch block. The exception is on the top of the stack.
generator.BeginCatchBlock(typeof(JavaScriptException));
// Create a new DeclarativeScope.
this.CatchScope.GenerateScopeCreation(generator, optimizationInfo);
// Store the error object in the variable provided.
generator.Call(ReflectionHelpers.JavaScriptException_ErrorObject);
var catchVariable = new NameExpression(this.CatchScope, this.CatchVariableName);
catchVariable.GenerateSet(generator, optimizationInfo, PrimitiveType.Any, false);
// Make sure the scope is reverted even if an exception is thrown.
generator.BeginExceptionBlock();
// Emit code for the statements within the catch block.
this.CatchBlock.GenerateCode(generator, optimizationInfo);
// Revert the scope.
generator.BeginFinallyBlock();
this.CatchScope.GenerateScopeDestruction(generator, optimizationInfo);
generator.EndExceptionBlock();
}
// Generate code for the finally block.
if (this.FinallyBlock != null)
{
generator.BeginFinallyBlock();
var branches = new List<ILLabel>();
var previousStackSize = optimizationInfo.LongJumpStackSizeThreshold;
optimizationInfo.LongJumpStackSizeThreshold = optimizationInfo.BreakOrContinueStackSize;
var previousCallback = optimizationInfo.LongJumpCallback;
optimizationInfo.LongJumpCallback = (generator2, label) =>
{
// It is not possible to branch out of a finally block - therefore instead of
// generating LEAVE instructions we throw an exception then catch it to transfer
// control out of the finally block.
generator2.LoadInt32(branches.Count);
generator2.NewObject(ReflectionHelpers.LongJumpException_Constructor);
generator2.Throw();
// Record any branches that are made within the finally code.
branches.Add(label);
};
// Emit code for the finally block.
this.FinallyBlock.GenerateCode(generator, optimizationInfo);
// End the main exception block.
generator.EndExceptionBlock();
// Begin a catch block to catch any LongJumpExceptions. The exception object is on
// the top of the stack.
generator.BeginCatchBlock(typeof(LongJumpException));
if (branches.Count > 0)
{
// switch (exception.RouteID)
// {
// case 0: goto label1;
// case 1: goto label2;
// }
ILLabel[] switchLabels = new ILLabel[branches.Count];
for (int i = 0; i < branches.Count; i++)
switchLabels[i] = generator.CreateLabel();
generator.Call(ReflectionHelpers.LongJumpException_RouteID);
generator.Switch(switchLabels);
for (int i = 0; i < branches.Count; i++)
{
generator.DefineLabelPosition(switchLabels[i]);
generator.Leave(branches[i]);
}
}
// Reset the state we clobbered.
optimizationInfo.LongJumpStackSizeThreshold = previousStackSize;
optimizationInfo.LongJumpCallback = previousCallback;
}
// End the exception block.
generator.EndExceptionBlock();
// Reset the InsideTryCatchOrFinally flag.
optimizationInfo.InsideTryCatchOrFinally = previousInsideTryCatchOrFinally;
// Generate code for the end of the statement.
GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
}
示例2: EmitLongJump
/// <summary>
/// Emits code to branch between statements, even if code generation is within a finally
/// block (where unconditional branches are not allowed).
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="targetLabel"> The label to jump to. </param>
public void EmitLongJump(ILGenerator generator, ILLabel targetLabel)
{
if (this.LongJumpCallback == null)
{
// Code generation is not inside a finally block.
if (this.InsideTryCatchOrFinally == true)
generator.Leave(targetLabel);
else
generator.Branch(targetLabel);
}
else
{
// The long jump is occurring within a finally block.
// Check if the target is inside or outside the finally block.
int depth = this.GetBreakOrContinueLabelDepth(targetLabel);
if (depth < this.LongJumpStackSizeThreshold)
{
// The target label is outside the finally block. Call the callback to emit
// the jump.
this.LongJumpCallback(generator, targetLabel);
}
else
{
// The target label is inside the finally block.
if (this.InsideTryCatchOrFinally == true)
generator.Leave(targetLabel);
else
generator.Branch(targetLabel);
}
}
}