private IEnumerable <Action <Label> > WriteUnrolledCatchBlocks(ILWriter writer, IImmutableQueue <Type> exceptionTypes, LocalBuilder shouldRetry, LocalBuilder currentExecutionAttempt) { var handleException = KnownMetadata.Methods.IExceptionAwareAction_HandleException; foreach (var exceptionType in exceptionTypes) { yield return(endOfTryCatch => { var handleSpecificException = handleException.MakeGenericMethod(exceptionType); Action catchBlockBody = () => { var endOfCatch = writer.DefineLabel(); var localException = writer.DeclareLocal(exceptionType); writer.SetLocal(localException); writer.LoadFirstParameter(); //Exception-aware instance writer.LoadLocal(localException); writer.LoadLocal(currentExecutionAttempt); writer.InstanceMethodCall(handleSpecificException); //The handler refusing to handle it indicates that we should perform a retry. var wasHandled = writer.IfFalseThen(); writer.LoadTrue(); writer.SetLocal(shouldRetry); writer.GoTo(endOfCatch); writer.MarkLabel(wasHandled); writer.LoadFalse(); writer.SetLocal(shouldRetry); writer.MarkLabel(endOfCatch); }; writer.CatchBlock(exceptionType, endOfTryCatch, catchBlockBody); }); } }