Exemplo n.º 1
0
        Instruction ReplaceStore(ILProcessor ilProcessor, Instruction instruction, MethodReference calledMethod)
        {
            var generic_method = calledMethod as GenericInstanceMethod;
            var typetok        = generic_method.GenericArguments[0];

            var stack = Analysis[instruction.Previous];

            var operandEntry     = stack.Head;
            var addr_instruction = operandEntry.Item1;
            var next             = instruction.Next;

            if (addr_instruction.OpCode == OpCodes.Ldloca)
            {
                var local = (VariableDefinition)addr_instruction.Operand;
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Stloc, local));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldarga)
            {
                var argument = (ParameterDefinition)addr_instruction.Operand;
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Starg, argument));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldsflda)
            {
                var field = (FieldReference)addr_instruction.Operand;
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Stsfld, field));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldflda)
            {
                var field = (FieldReference)addr_instruction.Operand;

                var value_temp = new VariableDefinition(field.FieldType);
                VariableDefinition addr_temp;
                if (field.DeclaringType.IsValueType)
                {
                    addr_temp = new VariableDefinition(field.DeclaringType.MakeByReferenceType());
                }
                else
                {
                    addr_temp = new VariableDefinition(field.DeclaringType);
                }

                ilProcessor.Body.Variables.Add(value_temp);
                ilProcessor.Body.Variables.Add(addr_temp);

                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Stloc, addr_temp));
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Stloc, value_temp));
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Ldloc, addr_temp));
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Ldloc, value_temp));
                ilProcessor.InsertBefore(addr_instruction, Instruction.Create(OpCodes.Stfld, field));
            }
            else
            {
                throw new Exception("ReplaceStore: How did we get here?!");
            }

            StackAnalyser.RemoveInstruction(ilProcessor, addr_instruction);
            StackAnalyser.RemoveInstruction(ilProcessor, instruction);

            return(next);
        }
Exemplo n.º 2
0
        protected override Instruction Visit(ILProcessor ilProcessor, Instruction instruction)
        {
            var calledMethod = instruction.Operand as MethodReference;
            var next         = instruction.Next;

            if (calledMethod.Name == "KeepAlive")
            {
                StackAnalyser.RemoveInstructionChain(ilProcessor.Body.Method, instruction, Analysis);
            }
            else if (calledMethod.Name == "Load" || calledMethod.Name == "Peek")
            {
                /*
                 * The compiler will have inserted the appropriate load
                 * instructions to put the value on the operand stack in
                 * preperation to call Load<T>. Thus all we have to do is
                 * remove the call instruction, that keeps the value on the
                 * stack instead of popping it for the call.
                 */
                StackAnalyser.RemoveInstruction(ilProcessor, instruction);
            }
            else if (calledMethod.Name == "LoadAddress")
            {
                /*
                 * The compiler will have inserted the a load instruction, we
                 * need to change it to the appropriate load address instruction.
                 */
                return(ReplaceLoadAddress(ilProcessor, instruction, calledMethod));
            }
            else if (calledMethod.Name == "Store")
            {
                /*
                 * The compiler will have inserted instructions to load the
                 * addr of the location we want to store to. We need to look
                 * at these instructions and replace them with the appropriate
                 * standard store instruction. We then remove the call to Store.
                 */

                return(ReplaceStore(ilProcessor, instruction, calledMethod));
            }
            else if (calledMethod.Name == "LoadByName")
            {
                return(ReplaceLoadByName(ilProcessor, instruction, calledMethod));
            }
            else if (calledMethod.Name == "StoreByName")
            {
                return(ReplaceStoreByName(ilProcessor, instruction, calledMethod));
            }
            else if (calledMethod.Name == "LoadAddressByName")
            {
                return(ReplaceLoadAddressByName(ilProcessor, instruction, calledMethod));
            }
            else if (calledMethod.Name == "DeclareLocal")
            {
                return(ReplaceDeclareLocal(ilProcessor, instruction, calledMethod));
            }
            else
            {
                return(ReplaceInstruction(ilProcessor, instruction, calledMethod));
            }

            return(next);
        }
Exemplo n.º 3
0
        private Instruction ReplaceLoadAddress(ILProcessor ilProcessor, Instruction instruction, MethodReference calledMethod)
        {
            var generic_method = calledMethod as GenericInstanceMethod;
            var typetok        = generic_method.GenericArguments[0];

            var stack = Analysis[instruction.Previous];

            var operandEntry     = stack.Head;
            var addr_instruction = operandEntry.Item1;
            var next             = instruction.Next;

            if (addr_instruction.OpCode == OpCodes.Ldloc)
            {
                var local = (VariableDefinition)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldloca, local));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldarg)
            {
                var argument = (ParameterDefinition)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldarga, argument));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldsfld)
            {
                var field = (FieldReference)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldsflda, field));
            }
            else if (addr_instruction.OpCode == OpCodes.Ldfld)
            {
                var field = (FieldReference)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldflda, field));
            }
            else if (
                addr_instruction.OpCode == OpCodes.Ldelem_Any)
            {
                var type = (TypeReference)addr_instruction.Operand;
                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldelema, type));
            }
            else if (
                addr_instruction.OpCode == OpCodes.Ldelem_I ||
                addr_instruction.OpCode == OpCodes.Ldelem_I1 ||
                addr_instruction.OpCode == OpCodes.Ldelem_I2 ||
                addr_instruction.OpCode == OpCodes.Ldelem_I4 ||
                addr_instruction.OpCode == OpCodes.Ldelem_I8 ||
                addr_instruction.OpCode == OpCodes.Ldelem_U1 ||
                addr_instruction.OpCode == OpCodes.Ldelem_U2 ||
                addr_instruction.OpCode == OpCodes.Ldelem_U4 ||
                addr_instruction.OpCode == OpCodes.Ldelem_R4 ||
                addr_instruction.OpCode == OpCodes.Ldelem_R8 ||
                addr_instruction.OpCode == OpCodes.Ldelem_Ref)
            {
                var module = ilProcessor.Body.Method.Module;

                TypeReference type;
                switch (addr_instruction.OpCode.Code)
                {
                case Code.Ldelem_I:
                    type = new TypeReference("System", "IntPtr", module, module);
                    break;

                case Code.Ldelem_I1:
                    type = new TypeReference("System", "SByte", module, module);
                    break;

                case Code.Ldelem_I2:
                    type = new TypeReference("System", "Int16", module, module);
                    break;

                case Code.Ldelem_I4:
                    type = new TypeReference("System", "Int32", module, module);
                    break;

                case Code.Ldelem_I8:
                    type = new TypeReference("System", "Int64", module, module);
                    break;

                case Code.Ldelem_U1:
                    type = new TypeReference("System", "Byte", module, module);
                    break;

                case Code.Ldelem_U2:
                    type = new TypeReference("System", "UInt16", module, module);
                    break;

                case Code.Ldelem_U4:
                    type = new TypeReference("System", "UInt32", module, module);
                    break;

                case Code.Ldelem_R4:
                    type = new TypeReference("System", "Single", module, module);
                    break;

                case Code.Ldelem_R8:
                    type = new TypeReference("System", "Double", module, module);
                    break;

                case Code.Ldelem_Ref:
                default:
                {
                    // array is the lower item in the stack
                    var array_instruction = Analysis[addr_instruction.Previous].Tail.Head.Item1;
                    // whatever load loaded this array it will have a type with it
                    type = array_instruction.Operand as TypeReference;
                }
                break;
                }

                StackAnalyser.ReplaceInstruction(ilProcessor, addr_instruction, Instruction.Create(OpCodes.Ldelema, type));
            }
            else
            {
                throw new Exception("ReplaceLoadAddress: How did we get here?!");
            }

            StackAnalyser.RemoveInstruction(ilProcessor, instruction);

            return(next);
        }