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"); }
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)); } } }