本文整理汇总了C#中Jurassic.Compiler.ILGenerator.BeginFinallyBlock方法的典型用法代码示例。如果您正苦于以下问题:C# ILGenerator.BeginFinallyBlock方法的具体用法?C# ILGenerator.BeginFinallyBlock怎么用?C# ILGenerator.BeginFinallyBlock使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Jurassic.Compiler.ILGenerator
的用法示例。
在下文中一共展示了ILGenerator.BeginFinallyBlock方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: GenerateCode
/// <summary>
/// Generates CIL for the statement.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Generate code for the start of the statement.
var statementLocals = new StatementLocals();
GenerateStartOfStatement(generator, optimizationInfo, statementLocals);
// Create the scope.
this.Scope.GenerateScopeCreation(generator, optimizationInfo);
// Make sure the scope is reverted even if an exception is thrown.
generator.BeginExceptionBlock();
// Setting the InsideTryCatchOrFinally flag converts BR instructions into LEAVE
// instructions so that the finally block is executed correctly.
var previousInsideTryCatchOrFinally = optimizationInfo.InsideTryCatchOrFinally;
optimizationInfo.InsideTryCatchOrFinally = true;
// Generate code for the body statements.
this.Body.GenerateCode(generator, optimizationInfo);
// Reset the InsideTryCatchOrFinally flag.
optimizationInfo.InsideTryCatchOrFinally = previousInsideTryCatchOrFinally;
// Revert the scope.
generator.BeginFinallyBlock();
this.Scope.GenerateScopeDestruction(generator, optimizationInfo);
generator.EndExceptionBlock();
// Generate code for the end of the statement.
GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
}
示例2: GenerateCode
/// <summary>
/// Generates CIL for the statement.
/// </summary>
/// <param name="generator"> The generator to output the CIL to. </param>
/// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
public override void GenerateCode(ILGenerator generator, OptimizationInfo optimizationInfo)
{
// Generate code for the start of the statement.
var statementLocals = new StatementLocals() { NonDefaultSourceSpanBehavior = true };
GenerateStartOfStatement(generator, optimizationInfo, statementLocals);
// Unlike in .NET, in javascript there are no restrictions on what can appear inside
// try, catch and finally blocks. The one restriction which causes problems is the
// inability to jump out of .NET finally blocks. This is required when break, continue
// or return statements appear inside of a finally block. To work around this, when
// inside a finally block these instructions throw an exception instead.
// Setting the InsideTryCatchOrFinally flag converts BR instructions into LEAVE
// instructions so that the finally block is executed correctly.
var previousInsideTryCatchOrFinally = optimizationInfo.InsideTryCatchOrFinally;
optimizationInfo.InsideTryCatchOrFinally = true;
// Finally requires two exception nested blocks.
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();
//.........这里部分代码省略.........
示例3: GenerateCode
//.........这里部分代码省略.........
previousVariableTypes = new List<KeyValuePair<Scope.DeclaredVariable, RevertInfo>>();
var typedVariables = FindTypedVariables();
foreach (var variableAndType in typedVariables)
{
var variable = variableAndType.Key;
var variableInfo = variableAndType.Value;
if (variableInfo.Conditional == false && variableInfo.Type != variable.Type)
{
// Save the previous type so we can restore it later.
var previousType = variable.Type;
previousVariableTypes.Add(new KeyValuePair<Scope.DeclaredVariable, RevertInfo>(variable, new RevertInfo() { Type = previousType, Variable = variable.Store }));
// Load the existing value.
var nameExpression = new NameExpression(variable.Scope, variable.Name);
nameExpression.GenerateGet(generator, optimizationInfo, false);
// Store the typed value.
variable.Store = generator.DeclareVariable(variableInfo.Type);
variable.Type = variableInfo.Type;
nameExpression.GenerateSet(generator, optimizationInfo, previousType, false);
}
}
// The variables must be reverted even in the presence of exceptions.
if (previousVariableTypes.Count > 0)
{
generator.BeginExceptionBlock();
// Setting the InsideTryCatchOrFinally flag converts BR instructions into LEAVE
// instructions so that the finally block is executed correctly.
optimizationInfo.InsideTryCatchOrFinally = true;
}
}
// The inner loop starts here.
var startOfLoop = generator.DefineLabelPosition();
// Check the condition and jump to the end if it is false.
if (this.ConditionStatement != null)
{
optimizationInfo.MarkSequencePoint(generator, this.ConditionStatement.SourceSpan);
this.Condition.GenerateCode(generator, optimizationInfo);
EmitConversion.ToBool(generator, this.Condition.ResultType);
generator.BranchIfFalse(breakTarget2);
}
// Emit the loop body.
optimizationInfo.PushBreakOrContinueInfo(this.Labels, breakTarget2, continueTarget, labelledOnly: false);
this.Body.GenerateCode(generator, optimizationInfo);
optimizationInfo.PopBreakOrContinueInfo();
// The continue statement jumps here.
generator.DefineLabelPosition(continueTarget);
// Increment the loop variable.
if (this.IncrementStatement != null)
this.IncrementStatement.GenerateCode(generator, optimizationInfo);
// Unconditionally branch back to the start of the loop.
generator.Branch(startOfLoop);
// Define the end of the loop (actually just after).
generator.DefineLabelPosition(breakTarget2);
// Revert the variable types.
if (previousVariableTypes != null && previousVariableTypes.Count > 0)
{
// Revert the InsideTryCatchOrFinally flag.
optimizationInfo.InsideTryCatchOrFinally = previousInsideTryCatchOrFinally;
// Revert the variable types within a finally block.
generator.BeginFinallyBlock();
foreach (var previousVariableAndType in previousVariableTypes)
{
var variable = previousVariableAndType.Key;
var variableRevertInfo = previousVariableAndType.Value;
// Load the existing value.
var nameExpression = new NameExpression(variable.Scope, variable.Name);
nameExpression.GenerateGet(generator, optimizationInfo, false);
// Store the typed value.
var previousType = variable.Type;
variable.Store = variableRevertInfo.Variable;
variable.Type = variableRevertInfo.Type;
nameExpression.GenerateSet(generator, optimizationInfo, previousType, false);
}
// End the exception block.
generator.EndExceptionBlock();
}
// Define the end of the loop (actually just after).
generator.DefineLabelPosition(breakTarget1);
// Generate code for the end of the statement.
GenerateEndOfStatement(generator, optimizationInfo, statementLocals);
}