private void RewriteInspectMemoryGraph(MethodDefinition method, ILProcessor il, Instruction call, IWorkSession session, ArgumentMethods argumentMethods)
        {
            var sequencePoint = FindClosestSequencePoint(method, call);

            if (sequencePoint == null)
            {
                return;
            }

            var arguments = _languages[session.LanguageName]
                            .GetCallArgumentIdentifiers(session, sequencePoint.StartLine, sequencePoint.StartColumn);

            if (arguments.Length == 0)
            {
                return;
            }

            il.InsertBefore(call, il.CreateLdcI4Best(arguments.Length));
            il.InsertBefore(call, il.CreateCall(argumentMethods.AllocateNext));
            foreach (var argument in arguments)
            {
                il.InsertBefore(call, argument != null ? il.Create(OpCodes.Ldstr, argument) : il.Create(OpCodes.Ldnull));
                il.InsertBefore(call, il.CreateCall(argumentMethods.AddToNext));
            }
        }
Пример #2
0
        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 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;
        }
Пример #4
0
        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;
        }
Пример #5
0
 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;
 }
Пример #6
0
        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;
        }
Пример #7
0
 private void RewriteCatch(Instruction start, ILProcessor il, ReportMethods flow)
 {
     il.InsertBeforeAndRetargetAll(start, il.Create(OpCodes.Dup));
     il.InsertBefore(start, il.CreateCall(flow.ReportException));
 }