/// <summary>
        /// Determines the number of values that are pushed onto the stack by this instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <returns>The number of values pushed onto the stack.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Occurs when the instruction's operation code provides an
        /// invalid stack behaviour.</exception>
        public static int GetStackPushCount(this CilInstruction instruction)
        {
            switch (instruction.OpCode.StackBehaviourPush)
            {
            case CilStackBehaviour.Push0:
                return(0);

            case CilStackBehaviour.Push1:
            case CilStackBehaviour.PushI:
            case CilStackBehaviour.PushI8:
            case CilStackBehaviour.PushR4:
            case CilStackBehaviour.PushR8:
            case CilStackBehaviour.PushRef:
                return(1);

            case CilStackBehaviour.Push1_Push1:
                return(2);

            case CilStackBehaviour.VarPush:
                return(DetermineVarPushCount(instruction));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Esempio n. 2
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);
        }
        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);
        }
Esempio n. 4
0
        /// <inheritdoc />
        protected override DispatchResult Execute(ExecutionContext context, CilInstruction instruction,
                                                  IntegerValue left, IntegerValue right)
        {
            var result = left.IsGreaterThan(right, instruction.OpCode.Code == CilCode.Cgt);

            return(ConvertToI4AndReturnSuccess(context, result));
        }
Esempio n. 5
0
 /// <inheritdoc />
 protected override DispatchResult Execute(ExecutionContext context, CilInstruction instruction,
                                           IntegerValue value, int shiftCount)
 {
     value.LeftShift(shiftCount);
     context.ProgramState.Stack.Push(value);
     return(DispatchResult.Success());
 }
Esempio n. 6
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            // Pop arguments.
            var indexValue = stack.Pop();
            var arrayValue = stack.Pop();

            // Check if both array and index are known.
            if (!arrayValue.IsKnown || !indexValue.IsKnown)
            {
                stack.Push(GetUnknownElementValue(context, instruction));
                return(base.Execute(context, instruction));
            }

            // Expect an int32 or a native int for index, and extract its value.
            if (indexValue.CliValueType != CliValueType.Int32 && indexValue.CliValueType != CliValueType.NativeInt)
            {
                return(DispatchResult.InvalidProgram());
            }
            int index = indexValue.InterpretAsI4().I32;

            // Obtain element.
            ICliValue elementValue;

            switch (arrayValue)
            {
            case OValue {
                    IsZero: { Value : TrileanValue.True }
            } :
                // Pushed array object is null.
                return(new DispatchResult(new NullReferenceException()));
Esempio n. 7
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);
        }
Esempio n. 8
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());
        }
Esempio n. 9
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);
        }
Esempio n. 10
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());
        }
Esempio n. 11
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());
        }
Esempio n. 12
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            // Pop arguments.
            var lengthValue        = (ICliValue)stack.Pop();
            var sourceAddress      = (ICliValue)stack.Pop();
            var destinationAddress = (ICliValue)stack.Pop();

            // Interpret arguments.
            if (!(destinationAddress is IPointerValue destinationPointer) || !(sourceAddress is IPointerValue sourcePointer))
            {
                return(DispatchResult.InvalidProgram());
            }

            if (!lengthValue.IsKnown)
            {
                throw new DispatchException("Number of bytes to copy is unknown.");
            }
            int length = lengthValue.InterpretAsI4().I32;

            // Copy data.
            Span <byte> data    = stackalloc byte[length];
            Span <byte> bitmask = stackalloc byte[length];

            sourcePointer.ReadBytes(0, data, bitmask);
            destinationPointer.WriteBytes(0, data, bitmask);

            return(base.Execute(context, instruction));
        }
        /// <summary>
        /// When this instruction is using a variant of the ldarg or starg opcodes, gets the parameter that is
        /// referenced by the instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="parameters">The parameters defined in the enclosing method body.</param>
        /// <returns>The parameter.</returns>
        /// <exception cref="ArgumentException">Occurs when the instruction is not using a variant of the ldarg or starg opcodes.</exception>
        public static Parameter GetParameter(this CilInstruction instruction, ParameterCollection parameters)
        {
            switch (instruction.OpCode.Code)
            {
            case CilCode.Ldarg:
            case CilCode.Ldarg_S:
            case CilCode.Ldarga:
            case CilCode.Ldarga_S:
            case CilCode.Starg:
            case CilCode.Starg_S:
                return((Parameter)instruction.Operand);

            case CilCode.Ldarg_0:
                return(parameters.GetBySignatureIndex(0));

            case CilCode.Ldarg_1:
                return(parameters.GetBySignatureIndex(1));

            case CilCode.Ldarg_2:
                return(parameters.GetBySignatureIndex(2));

            case CilCode.Ldarg_3:
                return(parameters.GetBySignatureIndex(3));

            default:
                throw new ArgumentException("Instruction is not a ldarg or starg instruction.");
            }
        }
        /// <summary>
        /// When this instruction is using a variant of the ldloc or stloc opcodes, gets the local variable that is
        /// referenced by the instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="variables">The local variables defined in the enclosing method body.</param>
        /// <returns>The variable.</returns>
        /// <exception cref="ArgumentException">Occurs when the instruction is not using a variant of the ldloc or stloc opcodes.</exception>
        public static CilLocalVariable GetLocalVariable(this CilInstruction instruction, IReadOnlyList <CilLocalVariable> variables)
        {
            switch (instruction.OpCode.Code)
            {
            case CilCode.Ldloc:
            case CilCode.Ldloc_S:
            case CilCode.Stloc:
            case CilCode.Stloc_S:
            case CilCode.Ldloca:
            case CilCode.Ldloca_S:
                return((CilLocalVariable)instruction.Operand);

            case CilCode.Ldloc_0:
            case CilCode.Stloc_0:
                return(variables[0]);

            case CilCode.Ldloc_1:
            case CilCode.Stloc_1:
                return(variables[1]);

            case CilCode.Ldloc_2:
            case CilCode.Stloc_2:
                return(variables[2]);

            case CilCode.Ldloc_3:
            case CilCode.Stloc_3:
                return(variables[3]);

            default:
                throw new ArgumentException("Instruction is not a ldloc or stloc instruction.");
            }
        }
Esempio n. 15
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);
        }
Esempio n. 16
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);
        }
Esempio n. 17
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);
        }
Esempio n. 18
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);
        }
Esempio n. 19
0
        /// <inheritdoc />
        protected override DispatchResult Execute(ExecutionContext context, CilInstruction instruction,
                                                  FValue left, FValue right)
        {
            bool result = left.IsLessThan(right, instruction.OpCode.Code == CilCode.Clt_Un);

            return(ConvertToI4AndReturnSuccess(context, result));
        }
Esempio n. 20
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);
        }
Esempio n. 21
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());
        }
Esempio n. 22
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);
        }
Esempio n. 23
0
File: Ceq.cs Progetto: lanicon/Echo
        /// <inheritdoc />
        protected override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction,
                                                  OValue left, OValue right)
        {
            var result = left.IsEqualTo(right);

            return(ConvertToI4AndReturnSuccess(context, result));
        }
Esempio n. 24
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);
        }
Esempio n. 25
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();

            var variables = new IVariable[1];

            if (environment.Architecture.GetReadVariables(instruction, variables) != 1)
            {
                throw new DispatchException(
                          $"Architecture returned an incorrect number of variables being read from instruction {instruction}.");
            }

            switch (variables[0])
            {
            case CilParameter parameter:
                var value = environment.CliMarshaller.ToCliValue(
                    context.ProgramState.Variables[variables[0]],
                    parameter.Parameter.ParameterType);

                context.ProgramState.Stack.Push(value);
                return(base.Execute(context, instruction));

            default:
                return(DispatchResult.InvalidProgram());
            }
        }
Esempio n. 26
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);
        }
Esempio n. 27
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);
        }
Esempio n. 28
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);
        }
Esempio n. 29
0
        /// <inheritdoc />
        public override DispatchResult Execute(CilExecutionContext context, CilInstruction instruction)
        {
            var environment = context.GetService <ICilRuntimeEnvironment>();
            var field       = ((IFieldDescriptor)instruction.Operand).Resolve();
            var stack       = context.ProgramState.Stack;

            var objectValue = stack.Pop();

            IConcreteValue fieldValue;

            if (field.IsStatic)
            {
                // Undocumented: The runtime does allow access of static fields through the ldfld opcode.
                // In this case, the object instance that is pushed is ignored, allowing constructs like:
                //
                //    ldnull
                //    ldfld <some_static_field>
                //
                // without the runtime throwing a NullReferenceException.

                var staticField = environment.StaticFieldFactory.Get(field);
                fieldValue = environment.CliMarshaller.ToCliValue(staticField.Value, field.Signature.FieldType);
            }
            else
            {
                // Attempt to dereference the object instance.

                switch (objectValue)
                {
                case { IsKnown: false } :
Esempio n. 30
0
        /// <inheritdoc />
        public override DispatchResult Execute(ExecutionContext context, CilInstruction instruction)
        {
            var stack = context.ProgramState.Stack;

            stack.Push((ICliValue)stack.Top.Copy());
            return(base.Execute(context, instruction));
        }