/// <summary> /// Starts a new catch block which handles exceptions of the given type based on the filter created by the given action /// </summary> /// <param name="exceptionType">The type of exception this catch block should handle</param> /// <param name="filter">An action that writes the IL comprising the filter block</param> public CatchBlock CatchBlock(Type exceptionType, Action <XsILGenerator> filter) { EnsureTryBlockEnded(); if (hasFinallyBlock) { throw new InvalidOperationException( "Exception block already has a finally block - cannot start new catch block"); } if (hasFaultBlock) { throw new InvalidOperationException( "Exception block already has a fault block - cannot have both catch and fault blocks"); } if (filter != null) { generator.BeginExceptFilterBlock(); if (exceptionType != null) { var filterBlockEnd = generator.DefineLabel(); var customFilter = generator.DefineLabel(); generator .Duplicate() .IsInstanceOfType(exceptionType) .BranchIfTrue(customFilter) .Pop() .LoadConstant(false) .BranchTo(filterBlockEnd); generator.MarkLabel(customFilter); filter(generator); generator.MarkLabel(filterBlockEnd); } else { filter(generator); } generator.BeginCatchBlock(null); } else { generator.BeginCatchBlock(exceptionType); } hasCatchBlocks = true; return(new CatchBlock(generator, endLabel)); }
internal static Label GetOrCreateLabel(this XsILGenerator generator, string labelName) { var data = GeneratorExtraData.GetOrCreateValue(generator); Label label; if (data.Labels.TryGetValue(labelName, out label)) { return(label); } else { label = generator.DefineLabel(); data.Labels.Add(labelName, label); return(label); } }
internal ExceptionBlock(XsILGenerator generator) { this.generator = generator; endLabel = generator.DefineLabel(); generator.BeginExceptionBlock(); }