protected override void ProcessMethod(TypeDesc type, XPathNavigator methodNav, object customData)
        {
            string signature = GetSignature(methodNav);

            if (string.IsNullOrEmpty(signature))
            {
                return;
            }

            MethodDesc method = FindMethod(type, signature);

            if (method == null)
            {
                // LogWarning(methodNav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName());
                return;
            }

            string action = GetAttribute(methodNav, "body");

            switch (action)
            {
            case "remove":
                _methodSubstitutions.Add(method, BodySubstitution.ThrowingBody);
                break;

            case "stub":
                BodySubstitution stubBody;
                if (method.Signature.ReturnType.IsVoid)
                {
                    stubBody = BodySubstitution.EmptyBody;
                }
                else
                {
                    stubBody = BodySubstitution.Create(TryCreateSubstitution(method.Signature.ReturnType, GetAttribute(methodNav, "value")));
                }

                if (stubBody != null)
                {
                    _methodSubstitutions[method] = stubBody;
                }
                else
                {
                    // Context.LogWarning ($"Invalid value for '{method.GetDisplayName ()}' stub", 2010, _xmlDocumentLocation);
                }
                break;

            default:
                //Context.LogWarning($"Unknown body modification '{action}' for '{method.GetDisplayName()}'", 2011, _xmlDocumentLocation);
                break;
            }
        }
示例#2
0
        public override MethodIL GetMethodIL(MethodDesc method)
        {
            BodySubstitution substitution = GetSubstitution(method);

            if (substitution != null)
            {
                return(substitution.EmitIL(method));
            }

            // BEGIN TEMPORARY WORKAROUND
            //
            // The following lines should just be:
            // return _nestedILProvider.GetMethodIL(method);
            // But we want to allow this to be used as a general-purpose IL provider.
            //
            // Rewriting all IL has compilation throughput hit we don't want.
            MethodIL result = _nestedILProvider.GetMethodIL(method);

            if (result != null)
            {
                var resultDef = result.GetMethodILDefinition();
                if (resultDef != result)
                {
                    MethodIL newBodyDef = GetMethodILWithInlinedSubstitutions(resultDef);

                    // If we didn't rewrite the body, we can keep the existing result.
                    if (newBodyDef != resultDef)
                    {
                        result = new InstantiatedMethodIL(method, newBodyDef);
                    }
                }
                else
                {
                    result = GetMethodILWithInlinedSubstitutions(result);
                }
            }
            return(result);
            // END TEMPORARY WORKAROUND
        }
示例#3
0
        private bool TryGetConstantArgument(MethodIL methodIL, byte[] body, OpcodeFlags[] flags, int offset, int argIndex, out int constant)
        {
            if ((flags[offset] & OpcodeFlags.BasicBlockStart) != 0)
            {
                constant = 0;
                return(false);
            }

            for (int currentOffset = offset - 1; currentOffset >= 0; currentOffset--)
            {
                if ((flags[currentOffset] & OpcodeFlags.InstructionStart) == 0)
                {
                    continue;
                }

                ILReader reader = new ILReader(body, currentOffset);
                ILOpcode opcode = reader.ReadILOpcode();
                if (opcode == ILOpcode.call || opcode == ILOpcode.callvirt)
                {
                    MethodDesc method = (MethodDesc)methodIL.GetObject(reader.ReadILToken());
                    if (argIndex == 0)
                    {
                        BodySubstitution substitution = GetSubstitution(method);
                        if (substitution != null && substitution.Value is int &&
                            (opcode != ILOpcode.callvirt || !method.IsVirtual))
                        {
                            constant = (int)substitution.Value;
                            return(true);
                        }
                        else
                        {
                            constant = 0;
                            return(false);
                        }
                    }

                    argIndex--;

                    if (method.Signature.Length > 0 || !method.Signature.IsStatic)
                    {
                        // We don't know how to skip over the parameters
                        break;
                    }
                }
                else if (opcode == ILOpcode.ldsfld)
                {
                    FieldDesc field = (FieldDesc)methodIL.GetObject(reader.ReadILToken());
                    if (argIndex == 0)
                    {
                        object substitution = GetSubstitution(field);
                        if (substitution is int)
                        {
                            constant = (int)substitution;
                            return(true);
                        }
                        else
                        {
                            constant = 0;
                            return(false);
                        }
                    }

                    argIndex--;
                }
                else if (opcode >= ILOpcode.ldc_i4_0 && opcode <= ILOpcode.ldc_i4_8)
                {
                    if (argIndex == 0)
                    {
                        constant = opcode - ILOpcode.ldc_i4_0;
                        return(true);
                    }

                    argIndex--;
                }
                else if (opcode == ILOpcode.ldc_i4)
                {
                    if (argIndex == 0)
                    {
                        constant = (int)reader.ReadILUInt32();
                        return(true);
                    }

                    argIndex--;
                }
                else if (opcode == ILOpcode.ldc_i4_s)
                {
                    if (argIndex == 0)
                    {
                        constant = (int)(sbyte)reader.ReadILByte();
                        return(true);
                    }

                    argIndex--;
                }
                else if ((opcode == ILOpcode.ldloc || opcode == ILOpcode.ldloc_s ||
                          (opcode >= ILOpcode.ldloc_0 && opcode <= ILOpcode.ldloc_3)) &&
                         ((flags[currentOffset] & OpcodeFlags.BasicBlockStart) == 0))
                {
                    // Paired stloc/ldloc that the C# compiler generates in debug code?
                    int locIndex = opcode switch
                    {
                        ILOpcode.ldloc => reader.ReadILUInt16(),
                        ILOpcode.ldloc_s => reader.ReadILByte(),
                        _ => opcode - ILOpcode.ldloc_0,
                    };

                    for (int potentialStlocOffset = currentOffset - 1; potentialStlocOffset >= 0; potentialStlocOffset--)
                    {
                        if ((flags[potentialStlocOffset] & OpcodeFlags.InstructionStart) == 0)
                        {
                            continue;
                        }

                        ILReader nestedReader = new ILReader(body, potentialStlocOffset);
                        ILOpcode otherOpcode  = nestedReader.ReadILOpcode();
                        if ((otherOpcode == ILOpcode.stloc || otherOpcode == ILOpcode.stloc_s ||
                             (otherOpcode >= ILOpcode.stloc_0 && otherOpcode <= ILOpcode.stloc_3)) &&
                            otherOpcode switch
                        {
                            ILOpcode.stloc => nestedReader.ReadILUInt16(),
                            ILOpcode.stloc_s => nestedReader.ReadILByte(),
                            _ => otherOpcode - ILOpcode.stloc_0,
                        } == locIndex)