void EmitUsing(LocalBuilder local, System.Action body) { var endFinally = IL.DefineLabel(); IL.BeginExceptionBlock(); body(); IL.BeginFinallyBlock(); IL.Emit(OpCodes.Ldloc, local); IL.Emit(OpCodes.Ldnull); IL.Emit(OpCodes.Beq, endFinally); IL.Emit(OpCodes.Ldloc, local); IL.Emit(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose")); IL.MarkLabel(endFinally); IL.EndExceptionBlock(); }
/// <summary> /// Start a new exception block. This is roughly analogous to a `try` block in C#, but an exception block contains it's catch and finally blocks. /// </summary> public ExceptionBlock BeginExceptionBlock() { if (MustMark) { MarkLabel(DefineLabel(AutoNamer.Next(this, "__autolabel"))); } UpdateState(Wrap(new[] { new StackTransition(0) }, "BeginExceptionBlock")); var labelDel = IL.BeginExceptionBlock(); var label = new Label(this, labelDel, AutoNamer.Next(this, "__exceptionBlockEnd")); CurrentLabels[label.Name] = label; var ret = new ExceptionBlock(label); TryBlocks[ret] = SigilTuple.Create(IL.Index, -1); CurrentExceptionBlock.Push(ret); return(ret); }
public override void Emit( ) { tryLabel = IL.BeginExceptionBlock(); }
private void EmitTryExpression(Expression expr) { var node = (TryExpression)expr; CheckTry(); //****************************************************************** // 1. ENTERING TRY //****************************************************************** PushLabelBlock(LabelScopeKind.Try); IL.BeginExceptionBlock(); //****************************************************************** // 2. Emit the try statement body //****************************************************************** EmitExpression(node.Body); var tryType = node.Type; LocalBuilder value = null; if (tryType != typeof(void)) { //store the value of the try body value = GetLocal(tryType); IL.Emit(OpCodes.Stloc, value); } //****************************************************************** // 3. Emit the catch blocks //****************************************************************** foreach (var cb in node.Handlers) { PushLabelBlock(LabelScopeKind.Catch); // Begin the strongly typed exception block if (cb.Filter == null) { IL.BeginCatchBlock(cb.Test); } else { IL.BeginExceptFilterBlock(); } EnterScope(cb); EmitCatchStart(cb); // // Emit the catch block body // EmitExpression(cb.Body); if (tryType != typeof(void)) { //store the value of the catch block body // ReSharper disable once AssignNullToNotNullAttribute IL.Emit(OpCodes.Stloc, value); } ExitScope(cb); PopLabelBlock(LabelScopeKind.Catch); } //****************************************************************** // 4. Emit the finally block //****************************************************************** if (node.Finally != null || node.Fault != null) { PushLabelBlock(LabelScopeKind.Finally); if (node.Finally != null) { IL.BeginFinallyBlock(); } else { IL.BeginFaultBlock(); } // Emit the body EmitExpressionAsVoid(node.Finally ?? node.Fault); IL.EndExceptionBlock(); PopLabelBlock(LabelScopeKind.Finally); } else { IL.EndExceptionBlock(); } if (tryType != typeof(void)) { // ReSharper disable once AssignNullToNotNullAttribute IL.Emit(OpCodes.Ldloc, value); FreeLocal(value); } PopLabelBlock(LabelScopeKind.Try); }
private void Try() { IL.BeginExceptionBlock(); // try { }
private void EmitTryExpression(Expression expr) { var node = (TryExpression)expr; CheckTry(_labelBlock); //****************************************************************** // 1. ENTERING TRY //****************************************************************** var parent = _labelBlock; _labelBlock = new LabelScopeInfo(parent, LabelScopeKind.Try); IL.BeginExceptionBlock(); //****************************************************************** // 2. Emit the try statement body //****************************************************************** EmitExpression(node.Body); var tryType = node.Type; LocalBuilder?value = null; if (tryType != typeof(void)) { //store the value of the try body value = GetLocal(tryType); IL.Emit(OpCodes.Stloc, value); } //****************************************************************** // 3. Emit the catch blocks //****************************************************************** foreach (var cb in node.Handlers) { var tmpParent = _labelBlock; _labelBlock = new LabelScopeInfo(tmpParent, LabelScopeKind.Catch); // Begin the strongly typed exception block if (cb.Filter == null) { IL.BeginCatchBlock(cb.Test); } else { IL.BeginExceptFilterBlock(); } var innerScopeInfo = GetInnerScope(node, _scope); if (innerScopeInfo.HasValue) { _scope = innerScopeInfo.Value.child.Enter(this, innerScopeInfo.Value.parent); } EmitCatchStart(cb); // // Emit the catch block body // EmitExpression(cb.Body); if (tryType != typeof(void)) { //store the value of the catch block body // ReSharper disable once AssignNullToNotNullAttribute IL.Emit(OpCodes.Stloc, value); } if (innerScopeInfo.HasValue) { innerScopeInfo.Value.child.Exit(); _scope = innerScopeInfo.Value.parent; } _labelBlock = tmpParent; } //****************************************************************** // 4. Emit the finally block //****************************************************************** if (node.Finally != null || node.Fault != null) { var tmpParent = _labelBlock; _labelBlock = new LabelScopeInfo(tmpParent, LabelScopeKind.Finally); if (node.Finally != null) { IL.BeginFinallyBlock(); } else { IL.BeginFaultBlock(); } // Emit the body EmitExpressionAsVoid(node.Finally ?? node.Fault !); IL.EndExceptionBlock(); _labelBlock = tmpParent; } else { IL.EndExceptionBlock(); } if (value != null) { // ReSharper disable once AssignNullToNotNullAttribute IL.Emit(OpCodes.Ldloc, value); FreeLocal(value); } _labelBlock = parent; }