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));
                }
            }
        }
        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);
            }
        }
Exemple #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));
            }
        }