public override void Emit() { //MarkSequencePoint(context); IL.BeginCatchBlock(exType.SharpType); EmitHelper.StormVar(IL, exSymbol.VarBuilder); StmtBody.Emit(); IL.EndExceptionBlock(); }
/// <summary> /// Begins a catch block for the given exception type in the given exception block. /// /// The given exception block must still be open. /// </summary> public CatchBlock BeginCatchBlock(ExceptionBlock forTry, Type exceptionType) { if (exceptionType == null) { throw new ArgumentNullException("exceptionType"); } if (forTry == null) { throw new ArgumentNullException("forTry"); } if (((IOwned)forTry).Owner != this) { FailOwnership(forTry); } if (CurrentExceptionBlock.Count > 0 && forTry != CurrentExceptionBlock.Peek()) { throw new InvalidOperationException("Cannot start CatchBlock on " + forTry + " while inner ExceptionBlock is still open"); } if (!typeof(Exception).IsAssignableFrom(exceptionType)) { throw new ArgumentException("BeginCatchBlock expects a type descending from Exception, found " + exceptionType, "exceptionType"); } var currentlyOpen = CatchBlocks.Where(c => c.Key.ExceptionBlock == forTry && c.Value.Item2 == -1).Select(s => s.Key).SingleOrDefault(); if (currentlyOpen != null) { throw new InvalidOperationException("Cannot start a new catch block, " + currentlyOpen + " has not been ended"); } if (MustMark) { MarkLabel(DefineLabel(AutoNamer.Next(this, "__autolabel"))); } UpdateState(Wrap(new[] { new StackTransition(0) }, "BeginCatchBlock")); var tryBlock = TryBlocks[forTry]; if (tryBlock.Item2 != -1) { throw new SigilVerificationException("BeginCatchBlock expects an unclosed exception block, but " + forTry + " is already closed", IL.Instructions(AllLocals)); } IL.BeginCatchBlock(exceptionType); UpdateState(Wrap(StackTransition.Push(exceptionType), "BeginCatchBlock")); var ret = new CatchBlock(exceptionType, forTry); CatchBlocks[ret] = SigilTuple.Create(IL.Index, -1); return(ret); }
private void Catch() { var ex = IL.DeclareLocal(typeof(Exception)); IL.BeginCatchBlock(typeof(Exception)); // catch IL.Emit(OpCodes.Stloc_S, ex); // (Exception ex) { InvokeOnError(ex); // _callHandler.AfterCall(obj, methodInfo, args); IL.EndExceptionBlock(); // } }
private void EmitCatchStart(CatchBlock cb) { if (cb.Filter == null) { EmitSaveExceptionOrPop(cb); return; } // emit filter block. Filter blocks are untyped so we need to do // the type check ourselves. var endFilter = IL.DefineLabel(); var rightType = IL.DefineLabel(); // skip if it's not our exception type, but save // the exception if it is so it's available to the // filter IL.Emit(OpCodes.Isinst, cb.Test); IL.Emit(OpCodes.Dup); IL.Emit(OpCodes.Brtrue, rightType); IL.Emit(OpCodes.Pop); IL.Emit(OpCodes.Ldc_I4_0); IL.Emit(OpCodes.Br, endFilter); // it's our type, save it and emit the filter. IL.MarkLabel(rightType); EmitSaveExceptionOrPop(cb); var parent = _labelBlock; _labelBlock = new LabelScopeInfo(parent, LabelScopeKind.Filter); EmitExpression(cb.Filter); _labelBlock = parent; // begin the catch, clear the exception, we've // already saved it IL.MarkLabel(endFilter); IL.BeginCatchBlock(null); IL.Emit(OpCodes.Pop); }
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 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; }