Exemplo n.º 1
0
        private IEnumerable <Instruction> StoreStringInEventData(BodyBuilder builder, VariableDefinition item, ParameterDefinition param)
        {
            var pinned  = builder.DeclareLocal(module.TypeSystem.String.MakePinnedType());
            var pointer = builder.DeclareLocal(module.TypeSystem.Char.MakePointerType());

            yield return(Instruction.Create(OpCodes.Ldarg, param));

            yield return(Instruction.Create(OpCodes.Stloc, pinned));

            yield return(Instruction.Create(OpCodes.Ldloc, pinned));

            yield return(Instruction.Create(OpCodes.Conv_I));

            yield return(Instruction.Create(OpCodes.Stloc, pointer));

            var isnull = builder.DefineLabel();

            yield return(Instruction.Create(OpCodes.Ldloc, pointer));

            yield return(Instruction.Create(OpCodes.Brfalse, isnull));

            yield return(Instruction.Create(OpCodes.Ldloc, pointer));

            yield return(Instruction.Create(OpCodes.Call, module.ImportReference(RuntimeHelpers_OffsetToStringData_Get)));

            yield return(Instruction.Create(OpCodes.Add));

            yield return(Instruction.Create(OpCodes.Stloc, pointer));

            yield return(isnull);

            yield return(Instruction.Create(OpCodes.Ldloc, item));

            yield return(Instruction.Create(OpCodes.Ldloc, pointer));

            yield return(Instruction.Create(OpCodes.Call, module.ImportReference(IntPtr_Op_Explicit)));

            yield return(Instruction.Create(OpCodes.Call, typeDefs.EventDataSetDataPointer));

            yield return(Instruction.Create(OpCodes.Ldnull));

            yield return(Instruction.Create(OpCodes.Stloc, pinned));

            // data[].Size = (SringArg.Length + 1) * 2
            yield return(Instruction.Create(OpCodes.Ldloc, item));

            yield return(Instruction.Create(OpCodes.Ldarg, param));

            yield return(Instruction.Create(OpCodes.Callvirt, module.ImportReference(String_Length_Get)));

            yield return(Instruction.Create(OpCodes.Ldc_I4_1));

            yield return(Instruction.Create(OpCodes.Add));

            yield return(Instruction.Create(OpCodes.Ldc_I4_2));

            yield return(Instruction.Create(OpCodes.Mul));

            yield return(Instruction.Create(OpCodes.Call, typeDefs.EventDataSetSize));
        }
Exemplo n.º 2
0
        private IEnumerable <Instruction> StoreBoolInEventData(BodyBuilder builder, VariableDefinition item, ParameterDefinition param)
        {
            var temp  = builder.DeclareLocal(module.TypeSystem.Int32, reusable: true);
            var @true = builder.DefineLabel();
            var @next = builder.DefineLabel();

            // var temp = param ? 1 : 0;
            yield return(Instruction.Create(OpCodes.Ldarg, param));

            yield return(Instruction.Create(OpCodes.Brtrue, @true));

            yield return(Instruction.Create(OpCodes.Ldc_I4_0));

            yield return(Instruction.Create(OpCodes.Br, @next));

            yield return(@true);

            yield return(Instruction.Create(OpCodes.Ldc_I4_1));

            yield return(@next);

            yield return(Instruction.Create(OpCodes.Stloc, temp));

            ////> item->Data = &temp;
            yield return(Instruction.Create(OpCodes.Ldloc, item));

            yield return(Instruction.Create(OpCodes.Ldloca, temp));

            yield return(Instruction.Create(OpCodes.Conv_U));

            yield return(Instruction.Create(OpCodes.Call, module.ImportReference(IntPtr_Op_Explicit)));

            yield return(Instruction.Create(OpCodes.Call, typeDefs.EventDataSetDataPointer));

            ////> item->Size = 4;
            yield return(Instruction.Create(OpCodes.Ldloc, item));

            yield return(Instruction.Create(OpCodes.Ldc_I4_4));

            yield return(Instruction.Create(OpCodes.Call, typeDefs.EventDataSetSize));
        }
Exemplo n.º 3
0
        private IEnumerable <Instruction> EmitBoolConvertCode(BodyBuilder builder)
        {
            var @true      = Instruction.Create(OpCodes.Ldc_I4, 1);
            var endOfBlock = builder.DefineLabel();

            yield return(Instruction.Create(OpCodes.Brtrue, @true));

            yield return(Instruction.Create(OpCodes.Ldc_I4, 0));

            yield return(Instruction.Create(OpCodes.Br, endOfBlock));

            yield return(@true);

            yield return(endOfBlock);
        }
Exemplo n.º 4
0
        protected void SetTraceMethodBody(MethodDefinition target, TraceMethod metadata, bool implementGuard = true)
        {
            target.CustomAttributes.Add(module.NewAttr(typeof(CompilerGeneratedAttribute)));

            var body = target.Body.Instructions;

            body.Clear();

            using (var builder = new BodyBuilder(target))
            {
                var exit = builder.DefineLabel();
                if (implementGuard)
                {
                    body.Add(EmitIsEnabledFallback());
                    body.Add(Instruction.Create(OpCodes.Brfalse, exit));
                }

                body.Add(WriteEvent(builder, target, metadata).ToArray());

                body.Add(exit);
                body.Add(Instruction.Create(OpCodes.Ret));
            }
        }
Exemplo n.º 5
0
        public override MethodDefinition BeforeMethod(MethodDefinition method)
        {
            if (!method.HasBody)
            {
                return(method);
            }

            TryDeclareExceptionsForLoggers(method);
            var calls = callCollector.Collect(method, logDefinitionFactory.IsLogger);

            if (calls.Length == 0)
            {
                return(method);
            }

            var collapsed = calls.SplitToSequences(new SameMethodComparer()).ToList();

            if (collapsed.Count == 0)
            {
                return(method);
            }

            log.Info($"Rewriting {method.FullName}");

            using (var builder = new BodyBuilder(method))
            {
                foreach (var callGroup in collapsed)
                {
                    var theCall = callGroup.First();
                    if (!logDefinitionFactory.TryGet(theCall.Call.TargetMethod().DeclaringType.Resolve(), out var info))
                    {
                        throw new InvalidOperationException("Log info should have been cached");
                    }

                    var start = theCall.StartsAt;                           // where the arguments start
                    var label = builder.DefineLabel();                      // jump target
                    var end   = callGroup.Last().Call;                      // the last call/callvirt in the sequence
                    var field = info.DeclareLoggerIn(method.DeclaringType); // the static field containing the logger instance
                    var guard = info.TryFindGuard(end);                     // the IsXXXEnabled method  (optional)

                    if (guard == null)
                    {
                        log.Warn($"There is no IsXXXEnabled defined for {end.TargetMethod()}, no check will be emitted");
                    }
                    else
                    {
                        builder.InsertBefore(start, Instruction.Create(OpCodes.Ldsfld, field));
                        builder.InsertBefore(start, Instruction.Create(OpCodes.Callvirt, guard));
                        builder.InsertBefore(start, Instruction.Create(OpCodes.Brfalse, label));
                    }

                    var logMethod = info.MapToILog(end);

                    foreach (var call in callGroup)
                    {
                        builder.InsertBefore(call.StartsAt, Instruction.Create(OpCodes.Ldsfld, field));

                        call.Call.OpCode  = OpCodes.Callvirt;
                        call.Call.Operand = logMethod;
                    }

                    if (guard != null)
                    {
                        builder.InsertAfter(end, label);
                    }
                }
            }

            return(method);
        }