Ejemplo n.º 1
0
        public void Rewriter(ILProcessor processor)
        {
            var constraineds = processor.Instructions
                               .OfType <OperandInstruction <Type> >()
                               .Where(i => i.OpCode == OpCodes.Constrained)
                               .ToList();

            foreach (var constrained in constraineds)
            {
                var constrainedType = constrained.Operand;
                var methodCall      = (OperandInstruction <MethodBase>)constrained.Next;

                //Remove the Constrained Instruction
                processor.Remove(constrained);

                //Check for a quick fix
                if (constrainedType.IsValueType)
                {
                    //Check if the value type directly implements the method or not
                    var realMethod =
                        StubGenerator.GetRuntimeMethodForVirtual(constrainedType, (MethodInfo)methodCall.Operand);
                    if (realMethod.DeclaringType == constrainedType)
                    {
                        //the method is directly implemented, just replace the CallVirt with a normal Call
                        processor.Replace(methodCall,
                                          OperandInstruction.Create <MethodBase>(OpCodes.Call, realMethod));

                        //For this case we are done!
                        continue;
                    }
                }

                //Find were the this pointer is pushed on the stack
                var thisInstruction = FindThisInstruction(methodCall);

                if (constrainedType.IsValueType) //the method is not directly implemented
                {
                    //ldobj struct
                    //box struct
                    //call virt

                    processor.InsertAfter(thisInstruction, new NoneInstruction(OpCodes.Box));
                    processor.InsertAfter(thisInstruction, new NoneInstruction(OpCodes.Ldobj));
                }
                else //this is a reference type
                {
                    //ldind_ref
                    //call virt

                    processor.InsertAfter(thisInstruction, new NoneInstruction(OpCodes.Ldind_Ref));
                }
            }
        }
Ejemplo n.º 2
0
        public void Rewriter(ILProcessor processor)
        {
            var branches = processor.Instructions
                           .OfType <OperandInstruction <ILProcessorInstruction> >()
                           .Where(i => OpCodesMap.ContainsKey(i.OpCode))
                           .ToList();

            if (!branches.Any())
            {
                return;
            }

            var offsets   = new Dictionary <ILProcessorInstruction, int>();
            var curOffset = 0;

            foreach (var instruction in processor.Instructions)
            {
                offsets.Add(instruction, curOffset);
                curOffset += GetInstructionSize(instruction);
            }

            while (branches.Any())
            {
                var branch = branches.FirstOrDefault(i =>
                {
                    var deltaOffset = offsets[i.Operand] - offsets[i.Next];
                    return(deltaOffset >= sbyte.MinValue && deltaOffset <= sbyte.MaxValue);
                });
                if (branch == null)
                {
                    break;
                }

                var shortFormOpCode = OpCodesMap[branch.OpCode];
                var shortBranch     = OperandInstruction.Create(shortFormOpCode, branch.Operand);
                processor.Replace(branch, shortBranch);

                //Update offsets
                ILProcessorInstruction loop = shortBranch;
                curOffset = offsets[branch];
                while (loop != null)
                {
                    offsets[loop] = curOffset;
                    curOffset    += GetInstructionSize(loop);

                    loop = loop.Next;
                }

                offsets.Remove(branch);
                branches.Remove(branch);
            }
        }
Ejemplo n.º 3
0
        public void Rewriter(ILProcessor processor)
        {
            var branches = processor.Instructions
                           .OfType <OperandInstruction <ILProcessorInstruction> >()
                           .Where(i => OpCodesMap.ContainsKey(i.OpCode))
                           .ToList();

            foreach (var instruction in branches)
            {
                var longFormOpCode = OpCodesMap[instruction.OpCode];
                processor.Replace(instruction, OperandInstruction.Create(longFormOpCode, instruction.Operand));
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Runs backwards through the instruction stream to find which instructions pushed the this pointer for this methodcall to the stack
        /// </summary>
        /// <param name="methodCall"></param>
        /// <returns></returns>
        private static ILProcessorInstruction FindThisInstruction(OperandInstruction <MethodBase> methodCall)
        {
            var numParameters      = methodCall.Operand.GetParameters().Length;
            var stackPos           = numParameters;
            var currentInstruction = methodCall.Prev;

            while (stackPos > 0 && currentInstruction != null)
            {
                stackPos += GetStackDelta(currentInstruction);

                currentInstruction = currentInstruction.Prev;
            }
            return(currentInstruction);
        }