Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        private TypeSpecification CreateDummyType()
        {
            var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", true);
            var image    = assembly.NetDirectory.MetadataHeader.LockMetadata();
            var importer = new ReferenceImporter(image);

            var typeSpec = (TypeSpecification)importer.ImportType(new TypeSpecification(image.TypeSystem.Void));

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

            method.CilMethodBody = new CilMethodBody(method)
            {
                Instructions =
                {
                    CilInstruction.Create(CilOpCodes.Ldtoken, typeSpec),
                    CilInstruction.Create(CilOpCodes.Pop),
                    CilInstruction.Create(CilOpCodes.Ret),
                }
            };
            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(method);

            return(typeSpec);
        }
Exemplo n.º 3
0
        public void OperandTypeArgument()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;
            var param1       = new ParameterSignature(image.TypeSystem.Boolean);
            var param2       = new ParameterSignature(image.TypeSystem.Int32);

            methodBody.Method.Signature = new MethodSignature(new[] { param1, param2 }, image.TypeSystem.Void);

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldarg, param1),
                CilInstruction.Create(CilOpCodes.Starg, param1),
                CilInstruction.Create(CilOpCodes.Ldarg, param2),
                CilInstruction.Create(CilOpCodes.Starg, param2),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(param1.ParameterType, ((ParameterSignature)instructions[0].Operand).ParameterType, _comparer);
            Assert.Equal(param1.ParameterType, ((ParameterSignature)instructions[1].Operand).ParameterType, _comparer);
            Assert.Equal(param2.ParameterType, ((ParameterSignature)instructions[2].Operand).ParameterType, _comparer);
            Assert.Equal(param2.ParameterType, ((ParameterSignature)instructions[3].Operand).ParameterType, _comparer);
        }
Exemplo n.º 4
0
        public void PersistentManagedFatMethodVariables()
        {
            const string expectedOutput = "Hello, world!";

            var assembly   = CreateTempAssembly();
            var image      = assembly.NetDirectory.MetadataHeader.Image;
            var importer   = new ReferenceImporter(image);
            var mainMethod = image.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == TypeName).Methods.First(x => x.Name == MainMethodName);

            mainMethod.CilMethodBody.Signature = new StandAloneSignature(
                new LocalVariableSignature(new[] { image.TypeSystem.String }));

            var instructions = mainMethod.CilMethodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, expectedOutput),
                CilInstruction.Create(CilOpCodes.Stloc_0),
                CilInstruction.Create(CilOpCodes.Ldloc_0),
                CilInstruction.Create(CilOpCodes.Call,
                                      importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }))),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            assembly.NetDirectory.MetadataHeader.UnlockMetadata();

            _context.VerifyOutput(assembly, expectedOutput);
        }
Exemplo n.º 5
0
        public void PersistentInstructions()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;
            var importer   = new ReferenceImporter(image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            var instructions = methodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Lorem Ipsum"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            Assert.Equal(instructions, newMethod.CilMethodBody.Instructions, new CilInstructionComparer());
        }
Exemplo n.º 6
0
        public void StackInbalanceLoop()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;
            var loopHead     = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                loopHead,
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                CilInstruction.Create(CilOpCodes.Add),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ldc_I4_0),
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Brtrue, loopHead),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            Assert.Throws <StackInbalanceException>(() => methodBody.ComputeMaxStack());
        }
Exemplo n.º 7
0
        public void OperandTypeVar()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;
            var var1         = new VariableSignature(image.TypeSystem.Boolean);
            var var2         = new VariableSignature(image.TypeSystem.Int32);

            methodBody.Signature = new StandAloneSignature(new LocalVariableSignature(new[] { var1, var2 }));

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldloc, var1),
                CilInstruction.Create(CilOpCodes.Stloc, var1),
                CilInstruction.Create(CilOpCodes.Ldloc, var2),
                CilInstruction.Create(CilOpCodes.Stloc, var2),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(var1.VariableType, ((VariableSignature)instructions[0].Operand).VariableType, _comparer);
            Assert.Equal(var1.VariableType, ((VariableSignature)instructions[1].Operand).VariableType, _comparer);
            Assert.Equal(var2.VariableType, ((VariableSignature)instructions[2].Operand).VariableType, _comparer);
            Assert.Equal(var2.VariableType, ((VariableSignature)instructions[3].Operand).VariableType, _comparer);
        }
Exemplo n.º 8
0
        public void OptimizeMacrosArguments()
        {
            var instructions = CreateDummyCollection(true);
            var method       = instructions.Owner.Method;

            for (int i = 0; i <= 256; i++)
            {
                method.Signature.Parameters.Add(new ParameterSignature(method.Image.TypeSystem.Object));
            }

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldarg, method.Signature.Parameters[0]),
                CilInstruction.Create(CilOpCodes.Ldarg, method.Signature.Parameters[1]),
                CilInstruction.Create(CilOpCodes.Ldarg, method.Signature.Parameters[255]),
                CilInstruction.Create(CilOpCodes.Ldarg, method.Signature.Parameters[256]),
            });

            instructions.OptimizeMacros();

            Assert.Equal(CilCode.Ldarg_0, instructions[0].OpCode.Code);
            Assert.Null(instructions[0].Operand);

            Assert.Equal(CilCode.Ldarg_1, instructions[1].OpCode.Code);
            Assert.Null(instructions[1].Operand);

            Assert.Equal(CilCode.Ldarg_S, instructions[2].OpCode.Code);
            Assert.Equal(method.Signature.Parameters[255], instructions[2].Operand);

            Assert.Equal(CilCode.Ldarg, instructions[3].OpCode.Code);
            Assert.Equal(method.Signature.Parameters[256], instructions[3].Operand);
        }
Exemplo n.º 9
0
        public void OperandTypeString()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;

            const string operand = "Lorem Ipsum Dolor Sit Amet";

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, operand),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(operand, instructions[0].Operand);
        }
Exemplo n.º 10
0
        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");
        }
Exemplo n.º 11
0
        public void EntrypointNotAdded()
        {
            // Create new assembly.
            var assembly  = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, false);
            var image     = assembly.NetDirectory.MetadataHeader.LockMetadata();
            var importer  = new ReferenceImporter(image);
            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            // Create but don't add main method.
            var main = new MethodDefinition("Main",
                                            MethodAttributes.Public | MethodAttributes.Static,
                                            new MethodSignature(image.TypeSystem.Void));

            main.CilMethodBody = new CilMethodBody(main);
            main.CilMethodBody.Instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Hello world!"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            image.ManagedEntrypoint = main;

            Assert.Throws <MemberNotImportedException>(() => image.Header.UnlockMetadata());
        }
Exemplo n.º 12
0
        public void OperandTypeField()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;
            var importer   = new ReferenceImporter(image);

            var instructions = methodBody.Instructions;

            var simpleField = importer.ImportField(typeof(Type).GetField("EmptyTypes", BindingFlags.Public | BindingFlags.Static));

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldsfld, simpleField),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(simpleField, instructions[0].Operand as IMemberReference, _comparer);
        }
Exemplo n.º 13
0
        public void PersistentEntrypoint()
        {
            // Create new assembly.
            var assembly  = NetAssemblyFactory.CreateAssembly(DummyAssemblyName, false);
            var image     = assembly.NetDirectory.MetadataHeader.LockMetadata();
            var importer  = new ReferenceImporter(image);
            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

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

            main.CilMethodBody = new CilMethodBody(main);
            main.CilMethodBody.Instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Hello world!"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret),
            });
            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(main);
            image.ManagedEntrypoint = main;

            // Commit.
            var mapping = image.Header.UnlockMetadata();

            // Test.
            Assert.Equal(mapping[main].ToUInt32(), assembly.NetDirectory.EntryPointToken);
            var newImage = assembly.NetDirectory.MetadataHeader.LockMetadata();

            Assert.Equal(main, newImage.ManagedEntrypoint, _comparer);
        }
Exemplo n.º 14
0
        public void OperandTypeSig()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;
            var importer   = new ReferenceImporter(image);

            var instructions = methodBody.Instructions;

            var signature = importer.ImportStandAloneSignature(
                new StandAloneSignature(new MethodSignature(image.TypeSystem.Void)
            {
                HasThis = false
            }));

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Calli, signature),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            var newSignature = (StandAloneSignature)instructions[0].Operand;

            Assert.Equal(signature.Signature as MethodSignature, newSignature.Signature as MethodSignature, _comparer);
        }
Exemplo n.º 15
0
        public void ComputeMaxStackConditionalBranch()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;
            var elseInstr    = CilInstruction.Create(CilOpCodes.Sub);
            var endInstr     = CilInstruction.Create(CilOpCodes.Call, writeLine);

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                CilInstruction.Create(CilOpCodes.Ldc_I4_0),
                CilInstruction.Create(CilOpCodes.Brtrue, elseInstr),
                CilInstruction.Create(CilOpCodes.Add),
                CilInstruction.Create(CilOpCodes.Br, endInstr),
                elseInstr,
                endInstr,
                CilInstruction.Create(CilOpCodes.Ret)
            });

            Assert.Equal(3, methodBody.ComputeMaxStack());
        }
Exemplo n.º 16
0
        public void OperandTypeType()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;
            var importer   = new ReferenceImporter(image);

            var instructions = methodBody.Instructions;

            var simpleType = importer.ImportType(typeof(Form));

            instructions.Add(CilInstruction.Create(CilOpCodes.Ldtoken, simpleType));
            instructions.Add(CilInstruction.Create(CilOpCodes.Pop));

            var genericType = importer.ImportType(typeof(List <Form>));

            instructions.Add(CilInstruction.Create(CilOpCodes.Ldtoken, genericType));
            instructions.Add(CilInstruction.Create(CilOpCodes.Pop));

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

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(simpleType, instructions[0].Operand as ITypeDescriptor, _comparer);
            Assert.Equal(genericType, instructions[2].Operand as ITypeDescriptor, _comparer);
        }
Exemplo n.º 17
0
        public void OptimizeMacrosThisParameter()
        {
            var instructions = CreateDummyCollection(false);
            var method       = instructions.Owner.Method;

            for (int i = 0; i < 2; i++)
            {
                method.Signature.Parameters.Add(new ParameterSignature(method.Image.TypeSystem.Object));
            }

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldarg, method.CilMethodBody.ThisParameter),
                CilInstruction.Create(CilOpCodes.Ldarg, method.Signature.Parameters[0]),
                CilInstruction.Create(CilOpCodes.Ldarg, method.Signature.Parameters[1]),
            });

            instructions.OptimizeMacros();

            Assert.Equal(CilCode.Ldarg_0, instructions[0].OpCode.Code);
            Assert.Null(instructions[0].Operand);
            Assert.Equal(CilCode.Ldarg_1, instructions[1].OpCode.Code);
            Assert.Null(instructions[1].Operand);
            Assert.Equal(CilCode.Ldarg_2, instructions[2].OpCode.Code);
            Assert.Null(instructions[2].Operand);
        }
Exemplo n.º 18
0
        public void OperandTypeInts()
        {
            const sbyte shortOperand = 0x12;
            const int   operand      = 0x1234;
            const long  longOperand  = 0x12345678;

            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_I4_S, shortOperand),
                CilInstruction.Create(CilOpCodes.Ldc_I4, operand),
                CilInstruction.Create(CilOpCodes.Ldc_I8, longOperand),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(shortOperand, instructions[0].Operand);
            Assert.Equal(operand, instructions[1].Operand);
            Assert.Equal(longOperand, instructions[2].Operand);
        }
Exemplo n.º 19
0
        public void OperandTypeSwitch()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;
            var target1      = CilInstruction.Create(CilOpCodes.Nop);
            var target2      = CilInstruction.Create(CilOpCodes.Nop);
            var target3      = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Switch, new[] { target1, target2, target3 }),
                target2,
                CilInstruction.Create(CilOpCodes.Ret),
                target1,
                CilInstruction.Create(CilOpCodes.Ret),
                target3,
                CilInstruction.Create(CilOpCodes.Ret),
            });

            methodBody.Instructions.CalculateOffsets();

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);
            var targets   = (IList <CilInstruction>)newMethod.CilMethodBody.Instructions[1].Operand;

            Assert.Equal(target1.Offset, targets[0].Offset);
            Assert.Equal(target2.Offset, targets[1].Offset);
            Assert.Equal(target3.Offset, targets[2].Offset);
        }
Exemplo n.º 20
0
        public void OperandTypeBranchTarget()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;
            var target1      = CilInstruction.Create(CilOpCodes.Nop);
            var target2      = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Br, target1),
                target2,
                CilInstruction.Create(CilOpCodes.Ret),
                target1,
                CilInstruction.Create(CilOpCodes.Br, target2),
            });

            methodBody.Instructions.CalculateOffsets();

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(target1.Offset, ((CilInstruction)instructions[0].Operand).Offset);
            Assert.Equal(target2.Offset, ((CilInstruction)instructions[4].Operand).Offset);
        }
Exemplo n.º 21
0
        public void OperandTypeReals()
        {
            const float  shortOperand = 0.1234F;
            const double operand      = 0.1234;

            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;

            var instructions = methodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_R4, shortOperand),
                CilInstruction.Create(CilOpCodes.Ldc_R8, operand),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(shortOperand, instructions[0].Operand);
            Assert.Equal(operand, instructions[1].Operand);
        }
Exemplo n.º 22
0
        public void PersistentExceptionHandlers()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;
            var importer   = new ReferenceImporter(image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;

            var tryStart     = CilInstruction.Create(CilOpCodes.Nop);
            var handlerStart = CilInstruction.Create(CilOpCodes.Pop);
            var handlerEnd   = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                tryStart,
                CilInstruction.Create(CilOpCodes.Ldc_I4_0),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Leave, handlerEnd),
                handlerStart,
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                CilInstruction.Create(CilOpCodes.Add),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Leave, handlerEnd),
                handlerEnd,
                CilInstruction.Create(CilOpCodes.Ret),
            });

            var exceptionType = importer.ImportType(typeof(Exception));

            methodBody.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Exception)
            {
                TryStart     = tryStart,
                TryEnd       = handlerStart,
                HandlerStart = handlerStart,
                HandlerEnd   = handlerEnd,
                CatchType    = exceptionType
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var instructionComparer = new CilInstructionComparer();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            Assert.Equal(1, newMethod.CilMethodBody.ExceptionHandlers.Count);
            var handler = newMethod.CilMethodBody.ExceptionHandlers[0];

            Assert.Equal(tryStart, handler.TryStart, instructionComparer);
            Assert.Equal(handlerStart, handler.TryEnd, instructionComparer);
            Assert.Equal(handlerStart, handler.HandlerStart, instructionComparer);
            Assert.Equal(handlerEnd, handler.HandlerEnd, instructionComparer);
            Assert.Equal(exceptionType, handler.CatchType, _comparer);
        }
Exemplo n.º 23
0
        public void PersistentNativeMethod()
        {
            var assembly = CreateTempAssembly();

            assembly.NetDirectory.Flags &= ~ImageNetDirectoryFlags.IlOnly;
            var image    = assembly.NetDirectory.MetadataHeader.Image;
            var importer = new ReferenceImporter(image);

            var nativeMethod = new MethodDefinition("MyNativeMethod",
                                                    MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.PInvokeImpl,
                                                    new MethodSignature(image.TypeSystem.Int32));

            nativeMethod.ImplAttributes = MethodImplAttributes.Native
                                          | MethodImplAttributes.Unmanaged
                                          | MethodImplAttributes.PreserveSig;

            var nativeBody = new X86MethodBody();

            nativeBody.Instructions.Add(new X86Instruction
            {
                Mnemonic = X86Mnemonic.Mov,
                OpCode   = X86OpCodes.Mov_Eax_Imm1632,
                Operand1 = new X86Operand(X86Register.Eax),
                Operand2 = new X86Operand(1337),
            });
            nativeBody.Instructions.Add(new X86Instruction
            {
                Mnemonic = X86Mnemonic.Retn,
                OpCode   = X86OpCodes.Retn,
            });

            nativeMethod.MethodBody = nativeBody;
            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(nativeMethod);

            var mainMethod = image.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == TypeName).Methods.First(x => x.Name == MainMethodName);

            var instructions = mainMethod.CilMethodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "The secret number is: {0}"),
                CilInstruction.Create(CilOpCodes.Call, nativeMethod),
                CilInstruction.Create(CilOpCodes.Box, importer.ImportType(typeof(int))),
                CilInstruction.Create(CilOpCodes.Call,
                                      importer.ImportMethod(
                                          typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }))),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            assembly.NetDirectory.MetadataHeader.UnlockMetadata();

            _context.VerifyOutput(assembly, "The secret number is: 1337");
        }
Exemplo n.º 24
0
        public void PersistentVTables()
        {
            var assembly = CreateTempAssembly();
            var header   = assembly.NetDirectory.MetadataHeader;
            var importer = new ReferenceImporter(header.Image);

            var type = new TypeDefinition(null, "SomeType", TypeAttributes.Public, importer.ImportType(typeof(object)));

            for (int i = 0; i < 10; i++)
            {
                var method = new MethodDefinition("Method" + i, MethodAttributes.Public | MethodAttributes.Virtual,
                                                  new MethodSignature(header.Image.TypeSystem.Void));
                method.MethodBody = new CilMethodBody(method)
                {
                    Instructions = { CilInstruction.Create(CilOpCodes.Ret) }
                };
                type.Methods.Add(method);
            }

            header.Image.Assembly.Modules[0].TopLevelTypes.Add(type);

            var mapping = header.UnlockMetadata();

            var directory    = new VTablesDirectory();
            var vTableHeader = new VTableHeader()
            {
                Attributes = VTableAttributes.Is32Bit,
            };

            foreach (var method in type.Methods)
            {
                vTableHeader.Table.Add(header.GetStream <TableStream>().ResolveRow(mapping[method]));
            }

            directory.VTableHeaders.Add(vTableHeader);

            assembly.NetDirectory.VTablesDirectory = directory;

            using (var stream = new MemoryStream())
            {
                assembly.Write(new BinaryStreamWriter(stream), new CompactNetAssemblyBuilder(assembly));

                assembly = WindowsAssembly.FromBytes(stream.ToArray());

                directory = assembly.NetDirectory.VTablesDirectory;
                Assert.NotNull(directory);
                Assert.Equal(1, directory.VTableHeaders.Count);
                Assert.Equal(type.Methods.Select(x => mapping[x]),
                             directory.VTableHeaders[0].Table.Select(x => x.MetadataToken));
            }
        }
Exemplo n.º 25
0
        public void ComputeMaxStackTestCall()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            var instructions = methodBody.Instructions;

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Lorem Ipsum"),
                CilInstruction.Create(CilOpCodes.Call, writeLine),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            Assert.Equal(1, methodBody.ComputeMaxStack());
        }
Exemplo n.º 26
0
        public void PersistentManagedFatMethodExceptionHandlers()
        {
            const string expectedOutput = "Hello, world!";

            var assembly   = CreateTempAssembly();
            var image      = assembly.NetDirectory.MetadataHeader.Image;
            var importer   = new ReferenceImporter(image);
            var mainMethod = image.Assembly.Modules[0].TopLevelTypes.First(x => x.Name == TypeName).Methods.First(x => x.Name == MainMethodName);

            var instructions = mainMethod.CilMethodBody.Instructions;
            var tryStart     = CilInstruction.Create(CilOpCodes.Nop);
            var handlerStart = CilInstruction.Create(CilOpCodes.Nop);
            var handlerEnd   = CilInstruction.Create(CilOpCodes.Nop);

            instructions.AddRange(new[]
            {
                tryStart,
                CilInstruction.Create(CilOpCodes.Ldstr, expectedOutput),
                CilInstruction.Create(CilOpCodes.Newobj, importer.ImportMethod(typeof(Exception).GetConstructor(new[] { typeof(string) }))),
                CilInstruction.Create(CilOpCodes.Throw),
                CilInstruction.Create(CilOpCodes.Leave, handlerEnd),

                handlerStart,
                CilInstruction.Create(CilOpCodes.Callvirt, importer.ImportMethod(typeof(Exception).GetMethod("get_Message"))),
                CilInstruction.Create(CilOpCodes.Call, importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }))),
                CilInstruction.Create(CilOpCodes.Leave_S, handlerEnd),
                handlerEnd,

                CilInstruction.Create(CilOpCodes.Ret),
            });

            mainMethod.CilMethodBody.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Exception)
            {
                TryStart     = tryStart,
                TryEnd       = handlerStart,
                HandlerStart = handlerStart,
                HandlerEnd   = handlerEnd,
                CatchType    = importer.ImportType(typeof(Exception))
            });

            assembly.NetDirectory.MetadataHeader.UnlockMetadata();

            _context.VerifyOutput(assembly, expectedOutput);
        }
Exemplo n.º 27
0
        private static unsafe bool TryOptimizeLdcI(CilInstructionExpression expression)
        {
            if (expression.Instructions.Count != 1 || expression.ExpectedType == null)
            {
                return(false);
            }

            var instruction = expression.Instructions[0];

            if (instruction.IsLdcI4)
            {
                int i4Value = instruction.GetLdcValue();
                if (!expression.ExpectedType.IsValueType)
                {
                    if (i4Value == 0)
                    {
                        // If ldc.i4.0 and expected type is a ref type, the ldc.i4.0 pushes null. We can therefore
                        // optimize to ldnull.
                        ReplaceWithSingleInstruction(expression, CilInstruction.Create(CilOpCodes.Ldnull));
                        return(true);
                    }
                }
                else if (expression.ExpectedType.IsTypeOf("System", "Single"))
                {
                    // KoiVM pushes floats using the pushi_dword instruction. Convert to ldc.r4 if a float is expected
                    // but an ldc.i4 instruction is pushing the value.
                    float actualValue = *(float *)&i4Value;
                    ReplaceWithSingleInstruction(expression, CilInstruction.Create(CilOpCodes.Ldc_R4, actualValue));
                    return(true);
                }
            }
            else if (instruction.OpCode.Code == CilCode.Ldc_I8 && expression.ExpectedType.IsTypeOf("System", "Double"))
            {
                // KoiVM pushes doubles using the pushi_qword instruction. Convert to ldc.r8 if a double is expected
                // but an ldc.i8 instruction is pushing the value.
                long   i8Value     = (long)instruction.Operand;
                double actualValue = *(double *)&i8Value;
                ReplaceWithSingleInstruction(expression, CilInstruction.Create(CilOpCodes.Ldc_R8, actualValue));
                return(true);
            }

            return(false);
        }
Exemplo n.º 28
0
        public void OperandTypeMethod()
        {
            var methodBody = CreateDummyMethodBody();
            var image      = methodBody.Method.Image;
            var importer   = new ReferenceImporter(image);

            var instructions = methodBody.Instructions;

            var simpleMethod = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

            var genericInstanceMethod = new MethodSpecification(
                new MemberReference(
                    importer.ImportType(typeof(Activator)),
                    "CreateInstance",
                    new MethodSignature(new GenericParameterSignature(GenericParameterType.Method, 0))
            {
                GenericParameterCount = 1,
                IsGeneric             = true
            }),
                new GenericInstanceMethodSignature(importer.ImportTypeSignature(typeof(Stream))));


            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldstr, "Some String"),
                CilInstruction.Create(CilOpCodes.Call, simpleMethod),
                CilInstruction.Create(CilOpCodes.Call, importer.ImportMethod(genericInstanceMethod)),
                CilInstruction.Create(CilOpCodes.Pop),
                CilInstruction.Create(CilOpCodes.Ret)
            });

            var mapping = image.Header.UnlockMetadata();

            image = image.Header.LockMetadata();

            var newMethod = (MethodDefinition)image.ResolveMember(mapping[methodBody.Method]);

            instructions = newMethod.CilMethodBody.Instructions;

            Assert.Equal(simpleMethod, instructions[1].Operand as IMemberReference, _comparer);
            Assert.Equal(genericInstanceMethod, instructions[2].Operand as IMemberReference, _comparer);
        }
Exemplo n.º 29
0
        public void NonExistentStreams()
        {
            var assembly = NetAssemblyFactory.CreateAssembly("SomeAssembly", true);
            var header   = assembly.NetDirectory.MetadataHeader;

            // Remove #US Stream.
            var usHeader = header.StreamHeaders.FirstOrDefault(x => x.Name == "#US");

            if (usHeader != null)
            {
                header.StreamHeaders.Remove(usHeader);
            }

            // Lock metadata.
            var image    = header.LockMetadata();
            var importer = new ReferenceImporter(image);

            // Create new method with a string.
            var method = new MethodDefinition("Test",
                                              MethodAttributes.Public | MethodAttributes.Static,
                                              new MethodSignature(image.TypeSystem.Void));

            method.CilMethodBody = new CilMethodBody(method)
            {
                Instructions =
                {
                    CilInstruction.Create(CilOpCodes.Ldstr,                                                       "Hello, world!"),
                    CilInstruction.Create(CilOpCodes.Call,                                                        importer.ImportMethod(
                                              typeof(Console).GetMethod("WriteLine",                              new[] { typeof(string) }))),
                    CilInstruction.Create(CilOpCodes.Ret)
                }
            };
            image.Assembly.Modules[0].TopLevelTypes[0].Methods.Add(method);

            // Commit changes.
            header.UnlockMetadata();

            // Check if #US stream is added again.
            var usStream = header.GetStream <UserStringStream>();

            Assert.NotNull(usStream);
        }
Exemplo n.º 30
0
        public void ComputeMaxStackBranch()
        {
            var methodBody = CreateDummyMethodBody();
            var importer   = new ReferenceImporter(methodBody.Method.Image);

            var writeLine = importer.ImportMethod(typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }));

            var instructions = methodBody.Instructions;
            var target       = CilInstruction.Create(CilOpCodes.Call, writeLine);

            instructions.AddRange(new[]
            {
                CilInstruction.Create(CilOpCodes.Ldc_I4_1),
                CilInstruction.Create(CilOpCodes.Br, target),
                CilInstruction.Create(CilOpCodes.Ldc_I4_2),
                target,
                CilInstruction.Create(CilOpCodes.Ret),
            });
            Assert.Equal(1, methodBody.ComputeMaxStack());
        }