public void ExtensionMethodTest()
        {
            var sourceAssembly = WindowsAssembly.FromFile(typeof(StaticClass).Assembly.Location);
            var sourceImage    = sourceAssembly.NetDirectory.MetadataHeader.LockMetadata();

            var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", false);
            var header   = assembly.NetDirectory.MetadataHeader;
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);
            var cloner   = new MemberCloner(image);

            var staticClass = sourceImage.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == "StaticClass");
            var clonedType  = cloner.CloneType(staticClass);

            var main = new MethodDefinition("Main", MethodAttributes.Public | MethodAttributes.Static,
                                            new MethodSignature(image.TypeSystem.Void));

            main.CilMethodBody = new CilMethodBody(main);
            var instructions = main.CilMethodBody.Instructions;

            instructions.Add(CilInstruction.Create(CilOpCodes.Ldc_I4_1));
            instructions.Add(CilInstruction.Create(CilOpCodes.Call,
                                                   clonedType.Methods.First(x => x.Name == "SomeExtension")));
            instructions.Add(CilInstruction.Create(CilOpCodes.Call,
                                                   importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }))));
            instructions.Add(CilInstruction.Create(CilOpCodes.Ret));

            image.Assembly.Modules[0].TopLevelTypes.Add(clonedType);
            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main);
            image.ManagedEntrypoint = main;

            header.UnlockMetadata();

            _context.VerifyOutput(assembly, "4");
        }
Beispiel #2
0
        public static TypeDefinition ImportFlagHelper(MetadataImage image, VMConstants constants)
        {
            // Clone flag helper class.
            var cloner         = new MemberCloner(image);
            var flagHelperType = cloner.CloneType(VmHelperType);

            image.Assembly.Modules[0].TopLevelTypes.Add(flagHelperType);

            // Obtain static cctor.
            var constructor  = flagHelperType.Methods.First(x => x.IsConstructor && x.IsStatic);
            var instructions = constructor.CilMethodBody.Instructions;

            instructions.Clear();

            // Assign values of flags to the fields.
            foreach (var entry in constants.Flags.OrderBy(x => x.Value))
            {
                instructions.Add(CilInstruction.Create(CilOpCodes.Ldc_I4, entry.Key));
                instructions.Add(CilInstruction.Create(CilOpCodes.Stsfld,
                                                       flagHelperType.Fields.First(x => x.Name == "FL_" + entry.Value.ToString())));
            }

            instructions.Add(CilInstruction.Create(CilOpCodes.Ret));

            return(flagHelperType);
        }
        public void CloneParameterReferences()
        {
            var sourceAssembly = WindowsAssembly.FromFile(typeof(SimpleClass).Assembly.Location);
            var sourceImage    = sourceAssembly.NetDirectory.MetadataHeader.LockMetadata();

            var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", false);
            var header   = assembly.NetDirectory.MetadataHeader;
            var image    = header.LockMetadata();
            var cloner   = new MemberCloner(image);

            var variablesClass = sourceImage.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == "Variables");
            var clonedClass    = cloner.CloneType(variablesClass);

            image.Assembly.Modules[0].TopLevelTypes.Add(clonedClass);

            foreach (var clonedMethod in clonedClass.Methods.Where(x => x.CilMethodBody != null))
            {
                var body       = clonedMethod.CilMethodBody;
                var parameters = clonedMethod.Signature.Parameters;

                var originalBody       = variablesClass.Methods.First(x => x.Name == clonedMethod.Name).CilMethodBody;
                var originalParameters = originalBody.Method.Signature.Parameters;

                foreach (var instruction in body.Instructions.Where(x =>
                                                                    x.OpCode.OperandType == CilOperandType.InlineArgument ||
                                                                    x.OpCode.OperandType == CilOperandType.ShortInlineArgument))
                {
                    var originalInstruction = originalBody.Instructions.GetByOffset(instruction.Offset);
                    Assert.NotNull(instruction.Operand);
                    Assert.Equal(originalParameters.IndexOf((ParameterSignature)originalInstruction.Operand),
                                 parameters.IndexOf((ParameterSignature)instruction.Operand));
                }
            }
        }