public void Rewrite(AssemblyDefinition assembly, IWorkSession session) { foreach (var module in assembly.Modules) { foreach (var type in module.Types) { if (HasFlowSupressingCalls(type)) { return; } } } foreach (var module in assembly.Modules) { var flow = new ReportMethods { ReportLineStart = module.ImportReference(ReportLineStartMethod), ReportValue = module.ImportReference(ReportValueMethod), ReportRefValue = module.ImportReference(ReportRefValueMethod), ReportSpanValue = module.ImportReference(ReportSpanValueMethod), ReportRefSpanValue = module.ImportReference(ReportRefSpanValueMethod), ReportReadOnlySpanValue = module.ImportReference(ReportReadOnlySpanValueMethod), ReportRefReadOnlySpanValue = module.ImportReference(ReportRefReadOnlySpanValueMethod), ReportException = module.ImportReference(ReportExceptionMethod), }; foreach (var type in module.Types) { Rewrite(type, flow, session); } } }
private void InsertReportValue( ILProcessor il, Instruction instruction, Instruction getValue, TypeReference valueType, string valueName, int line, ReportMethods flow, ref int index ) { il.InsertBefore(instruction, getValue); il.InsertBefore(instruction, valueName != null ? il.Create(OpCodes.Ldstr, valueName) : il.Create(OpCodes.Ldnull)); il.InsertBefore(instruction, il.CreateLdcI4Best(line)); var report = flow.ReportValue; if (valueType is RequiredModifierType requiredType) { valueType = requiredType.ElementType; // not the same as GetElementType() which unwraps nested ref-types etc } if (valueType.IsByReference) { report = flow.ReportRefValue; valueType = valueType.GetElementType(); } il.InsertBefore(instruction, il.CreateCall(new GenericInstanceMethod(report) { GenericArguments = { valueType } })); index += 4; }
private void InsertReportValue( ILProcessor il, Instruction instruction, Instruction getValue, TypeReference valueType, string valueName, int line, ReportMethods flow, ref int index ) { il.InsertBefore(instruction, getValue); il.InsertBefore(instruction, valueName != null ? il.Create(OpCodes.Ldstr, valueName) : il.Create(OpCodes.Ldnull)); il.InsertBefore(instruction, il.CreateLdcI4Best(line)); if (valueType is RequiredModifierType requiredType) { valueType = requiredType.ElementType; // not the same as GetElementType() which unwraps nested ref-types etc } var report = PrepareReportValue(valueType, flow.ReportValue, flow.ReportSpanValue, flow.ReportReadOnlySpanValue); if (valueType is ByReferenceType byRef) { report = PrepareReportValue(byRef.ElementType, flow.ReportRefValue, flow.ReportRefSpanValue, flow.ReportRefReadOnlySpanValue); } il.InsertBefore(instruction, il.CreateCall(report)); index += 4; }
private void Rewrite(TypeDefinition type, ReportMethods flow, IWorkSession session) { foreach (var method in type.Methods) { Rewrite(method, flow, session); } }
private void RewriteExceptionHandlers(ILProcessor il, ReportMethods flow) { if (!il.Body.HasExceptionHandlers) { return; } var handlers = il.Body.ExceptionHandlers; for (var i = 0; i < handlers.Count; i++) { switch (handlers[i].HandlerType) { case ExceptionHandlerType.Catch: RewriteCatch(handlers[i].HandlerStart, il, flow); break; case ExceptionHandlerType.Filter: RewriteCatch(handlers[i].FilterStart, il, flow); break; case ExceptionHandlerType.Finally: RewriteFinally(handlers[i], ref i, il, flow); break; } } }
private void Rewrite(TypeDefinition type, ReportMethods flow) { foreach (var method in type.Methods) { Rewrite(method, flow); } }
private void btnReportAllByDate_Click(object sender, EventArgs e) { lstDisplay.Visible = false; dgvReports.DataSource = null; dgvReports.Rows.Clear(); dgvReports.DataSource = ReportMethods.ListOfBetsToDataTable(ReportMethods.BetsInDateOrder()); dgvReports.Visible = true; }
private void btnReportByYear_Click(object sender, EventArgs e) { lstDisplay.Visible = false; dgvReports.DataSource = null; dgvReports.Rows.Clear(); dgvReports.DataSource = ReportMethods.TotalWonLostToDataTable(ReportMethods.TotalBetsByYear()); dgvReports.Visible = true; }
private void btnReportSuccessRate_Click(object sender, EventArgs e) { dgvReports.Visible = false; lstDisplay.Items.Clear(); int[] totals = ReportMethods.HotTipsterStats(); lstDisplay.Items.Add(string.Format("The total number of bets is {0} and the total won is {1}.", totals[0], totals[1])); lstDisplay.Visible = true; }
private void btnReportMaxWinLose_Click(object sender, EventArgs e) { lstDisplay.Visible = false; dgvReports.DataSource = null; dgvReports.Rows.Clear(); dgvReports.DataSource = ReportMethods.ListOfBetsToDataTable(ReportMethods.BiggestWinAndBiggestLoss()); dgvReports.Visible = true; }
private void Rewrite(MethodDefinition method, ReportMethods flow, IWorkSession session) { if (!method.HasBody || method.Body.Instructions.Count == 0) { return; } var il = method.Body.GetILProcessor(); var instructions = il.Body.Instructions; var lastLine = (int?)null; for (var i = 0; i < instructions.Count; i++) { var instruction = instructions[i]; var sequencePoint = method.DebugInformation?.GetSequencePoint(instruction); var hasSequencePoint = sequencePoint != null && sequencePoint.StartLine != HiddenLine; if (!hasSequencePoint && lastLine == null) { continue; } if (hasSequencePoint && sequencePoint !.StartLine != lastLine) { if (i == 0) { TryInsertReportMethodArguments(il, instruction, sequencePoint, method, flow, session, ref i); } il.InsertBeforeAndRetargetAll(instruction, il.CreateLdcI4Best(sequencePoint.StartLine)); il.InsertBefore(instruction, il.CreateCall(flow.ReportLineStart)); i += 2; lastLine = sequencePoint.StartLine; } var valueOrNull = GetValueToReport(instruction, il, session); if (valueOrNull == null) { continue; } var value = valueOrNull.Value; InsertReportValue( il, instruction, il.Create(OpCodes.Dup), value.type, value.name, sequencePoint?.StartLine ?? lastLine ?? Flow.UnknownLineNumber, flow, ref i ); } RewriteExceptionHandlers(il, flow); }
private void Rewrite(MethodDefinition method, ReportMethods flow) { if (!method.HasBody || method.Body.Instructions.Count == 0) { return; } var il = method.Body.GetILProcessor(); var instructions = il.Body.Instructions; var lastLine = (int?)null; for (var i = 0; i < instructions.Count; i++) { var instruction = instructions[i]; var sequencePoint = instruction.SequencePoint; if (sequencePoint != null && sequencePoint.StartLine != HiddenLine && sequencePoint.StartLine != lastLine) { InsertBeforeAndRetargetAll(il, instruction, il.CreateLdcI4Best(sequencePoint.StartLine)); il.InsertBefore(instruction, il.CreateCall(flow.ReportLineStart)); i += 2; lastLine = sequencePoint.StartLine; } var value = GetValueToReport(instruction, il); if (value.name == null) { continue; } var insertTarget = instruction; il.InsertBefore(instruction, il.Create(OpCodes.Dup)); il.InsertBefore(instruction, il.Create(OpCodes.Ldstr, value.name)); il.InsertBefore(instruction, il.CreateLdcI4Best(sequencePoint?.StartLine ?? lastLine ?? Flow.UnknownLineNumber)); il.InsertBefore(instruction, il.CreateCall(new GenericInstanceMethod(flow.ReportValue) { GenericArguments = { value.type } })); i += 4; } RewriteExceptionHandlers(il, flow); }
public void Rewrite(AssemblyDefinition assembly, IWorkSession session) { foreach (var module in assembly.Modules) { var flow = new ReportMethods { ReportLineStart = module.ImportReference(ReportLineStartMethod), ReportValue = module.ImportReference(ReportValueMethod), ReportException = module.ImportReference(ReportExceptionMethod), }; foreach (var type in module.Types) { Rewrite(type, flow); foreach (var nested in type.NestedTypes) { Rewrite(nested, flow); } } } }
private void RewriteFinally(ExceptionHandler handler, ref int handlerIndex, ILProcessor il, ReportMethods flow) { // for try/finally, the only thing we can do is to // wrap internals of try into a new try+filter+catch var outerTryLeave = handler.TryEnd.Previous; if (!outerTryLeave.OpCode.Code.IsLeave()) { // in some cases (e.g. exception throw) outer handler does // not end with `leave` -- but we do need it once we wrap // that throw // if the handler is the last thing in the method if (handler.HandlerEnd == null) { var finalReturn = il.Create(OpCodes.Ret); il.Append(finalReturn); handler.HandlerEnd = finalReturn; } outerTryLeave = il.Create(OpCodes.Leave, handler.HandlerEnd); il.InsertBefore(handler.TryEnd, outerTryLeave); } var innerTryLeave = il.Create(OpCodes.Leave_S, outerTryLeave); var reportCall = il.CreateCall(flow.ReportException); var catchHandler = il.Create(OpCodes.Pop); il.InsertBeforeAndRetargetAll(outerTryLeave, innerTryLeave); il.InsertBefore(outerTryLeave, reportCall); il.InsertBefore(outerTryLeave, il.Create(OpCodes.Ldc_I4_0)); il.InsertBefore(outerTryLeave, il.Create(OpCodes.Endfilter)); il.InsertBefore(outerTryLeave, catchHandler); il.InsertBefore(outerTryLeave, il.Create(OpCodes.Leave_S, outerTryLeave)); for (var i = 0; i < handlerIndex; i++) { il.Body.ExceptionHandlers[i].RetargetAll(outerTryLeave.Next, innerTryLeave.Next); } il.Body.ExceptionHandlers.Insert(handlerIndex, new ExceptionHandler(ExceptionHandlerType.Filter) { TryStart = handler.TryStart, TryEnd = reportCall, FilterStart = reportCall, HandlerStart = catchHandler, HandlerEnd = outerTryLeave }); handlerIndex += 1; }
private void btnReportFavRaceCourse_Click(object sender, EventArgs e) { dgvReports.Visible = false; lstDisplay.Items.Add(string.Format("The most popular racecourse is {0}.", ReportMethods.RaceCourseWithMostBets())); lstDisplay.Visible = true; }
private void RewriteCatch(Instruction start, ILProcessor il, ReportMethods flow) { il.InsertBeforeAndRetargetAll(start, il.Create(OpCodes.Dup)); il.InsertBefore(start, il.CreateCall(flow.ReportException)); }
private void TryInsertReportMethodArguments(ILProcessor il, Instruction instruction, MethodDefinition method, ReportMethods flow, IWorkSession session, ref int index) { if (!method.HasParameters) { return; } var sequencePoint = instruction.SequencePoint; var parameterLines = _languages[session.LanguageName] .GetMethodParameterLines(session, sequencePoint.StartLine, sequencePoint.StartColumn); if (parameterLines.Length == 0) { return; } foreach (var parameter in method.Parameters) { if (parameter.ParameterType.IsByReference) { continue; } InsertReportValue( il, instruction, il.CreateLdargBest(parameter), parameter.ParameterType, parameter.Name, parameterLines[parameter.Index], flow, ref index ); } }
private void InsertReportValue(ILProcessor il, Instruction instruction, Instruction getValue, TypeReference valueType, string valueName, int line, ReportMethods flow, ref int index) { il.InsertBefore(instruction, getValue); il.InsertBefore(instruction, valueName != null ? il.Create(OpCodes.Ldstr, valueName) : il.Create(OpCodes.Ldnull)); il.InsertBefore(instruction, il.CreateLdcI4Best(line)); il.InsertBefore(instruction, il.CreateCall(new GenericInstanceMethod(flow.ReportValue) { GenericArguments = { valueType } })); index += 4; }
private void TryInsertReportMethodArguments(ILProcessor il, Instruction instruction, SequencePoint sequencePoint, MethodDefinition method, ReportMethods flow, IWorkSession session, ref int index) { if (!method.HasParameters) { return; } var parameterLines = _languages[session.LanguageName] .GetMethodParameterLines(session, sequencePoint.StartLine, sequencePoint.StartColumn); if (parameterLines.Length == 0) { return; } // Note: method parameter lines are unreliable and can potentially return // wrong lines if nested method syntax is unrecognized and code matches it // to the containing method. That is acceptable, as long as parameter count // mismatch does not crash things -> so check length here. if (parameterLines.Length != method.Parameters.Count) { return; } foreach (var parameter in method.Parameters) { if (parameter.IsOut) { continue; } InsertReportValue( il, instruction, il.CreateLdargBest(parameter), parameter.ParameterType, parameter.Name, parameterLines[parameter.Index], flow, ref index ); } }
private void RewriteFinally(ExceptionHandler handler, ref int handlerIndex, ILProcessor il, ReportMethods flow) { var oldTryLeave = handler.TryEnd.Previous; var newTryLeave = il.Create(OpCodes.Leave_S, (Instruction)oldTryLeave.Operand); var reportCall = il.CreateCall(flow.ReportException); var catchHandler = il.Create(OpCodes.Pop); InsertBeforeAndRetargetAll(il, oldTryLeave, newTryLeave); il.InsertBefore(oldTryLeave, reportCall); il.InsertBefore(oldTryLeave, il.Create(OpCodes.Ldc_I4_0)); il.InsertBefore(oldTryLeave, il.Create(OpCodes.Endfilter)); il.InsertBefore(oldTryLeave, catchHandler); for (var i = 0; i < handlerIndex; i++) { il.Body.ExceptionHandlers[i].RetargetAll(oldTryLeave.Next, newTryLeave.Next); } il.Body.ExceptionHandlers.Insert(handlerIndex, new ExceptionHandler(ExceptionHandlerType.Filter) { TryStart = handler.TryStart, TryEnd = reportCall, FilterStart = reportCall, HandlerStart = catchHandler, HandlerEnd = oldTryLeave.Next }); handlerIndex += 1; }