Esempio n. 1
0
        public void ModifyAssembly(string fileName)
        {
            MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });

            // ReaderParameters { ReadWrite = true } is necessary to later write the file
            using (ModuleDefinition module = ModuleDefinition.ReadModule(fileName, new ReaderParameters {
                ReadWrite = true
            }))
            {
                // Modify the assembly
                TypeDefinition[] types = module.Types.ToArray();

                MethodReference methodReference = module.ImportReference(writeLineMethod);

                foreach (var type in types)
                {
                    foreach (MethodDefinition methodToChange in type.Methods)
                    {
                        string sentence = String.Concat("Code added in ", methodToChange.Name);
                        Mono.Cecil.Cil.ILProcessor ilProcessor = methodToChange.Body.GetILProcessor();

                        Mono.Cecil.Cil.Instruction loadStringInstruction = ilProcessor.Create(OpCodes.Ldstr, sentence);
                        Mono.Cecil.Cil.Instruction callInstruction       = ilProcessor.Create(OpCodes.Call, methodReference);

                        Mono.Cecil.Cil.Instruction methodFirstInstruction = methodToChange.Body.Instructions[0];

                        ilProcessor.InsertBefore(methodFirstInstruction, loadStringInstruction);
                        ilProcessor.InsertAfter(loadStringInstruction, callInstruction);
                    }
                }

                module.Write(); // Write to the same file that was used to open the file
            }
        }
Esempio n. 2
0
		public static int[] BranchTargets (Instruction instruction)
		{
			if (instruction == null)
				throw new ArgumentNullException ("instruction");

			int[] result = null;
			switch (instruction.OpCode.OperandType) {
			case OperandType.InlineSwitch:
				Instruction[] targets = (Instruction[])instruction.Operand;
				result = new int[targets.Length];
				int i = 0;
				foreach (Instruction target in targets) {
					result [i] = target.Offset;
					i++;
				}
				break;
			case OperandType.InlineBrTarget:
				result = new int[1];
				result [0] = ((Instruction)instruction.Operand).Offset;
				break;
			case OperandType.ShortInlineBrTarget:
				result = new int[1];
				result [0] = ((Instruction)instruction.Operand).Offset;
				break;
			}
			return result;
		}
Esempio n. 3
0
        public static void Instance(JavaCode code, CodeLocals locals, Mono.Cecil.Cil.Instruction cilInst)
        {
            if (cilInst.Operand is TypeReference cilType && cilInst.Next != null)
            {
                var stackTop = (CilType)code.StackMap.PopStack(CilMain.Where);
                if (!stackTop.IsReference)
                {
                    throw new InvalidProgramException(); // top of stack is a primitive type
                }
                var      castType  = (CilType)CilType.From(cilType);
                JavaType castClass = CilType.From(cilType).AsWritableClass;

                if (GenericUtil.ShouldCallGenericCast(stackTop, castType) ||
                    castType.IsGenericParameter)
                {
                    code.StackMap.PushStack(stackTop);
                    // casting to a generic type is done via GenericType.TestCast
                    GenericUtil.CastToGenericType(cilType, 0, code);
                    code.StackMap.PopStack(CilMain.Where);  // stackTop
                    if (!castType.IsGenericParameter)
                    {
                        code.NewInstruction(0xC0 /* checkcast */, castClass, null);
                    }
                    code.StackMap.PushStack(castClass);
                }

                else if (CodeArrays.CheckCast(castType, false, code))
                {
                    // if casting to Object[], ValueType[], to an array of
                    // interface type, or to an array of a generic parameter,
                    // then CodeArrays.CheckCast already generated a call to
                    // system.Array.CheckCast in baselib, and we are done here

                    if (!castType.IsGenericParameter)
                    {
                        // avoid cast since T[] might be a primitive array
                        code.NewInstruction(0xC0 /* checkcast */, castClass, null);
                    }
                    code.StackMap.PushStack(castClass);
                }

                //
                // the cil 'isinst' casts the operand to the requested class,
                // but the jvm 'instanceof' only returns zero or one.  so we
                // also use 'checkcast' to get the jvm to acknowledge the cast
                //
                // however, if the cil 'isinst' is immediately followed by
                // 'brtrue' or 'brfalse' then we don't have to actually cast
                //

                else if (!TestForBranch(code, castClass, cilInst.Next))
                {
                    ushort nextLabel  = (ushort)cilInst.Next.Offset;
                    int    localIndex = locals.GetTempIndex(stackTop);

                    TestAndCast(code, castClass, stackTop, nextLabel, localIndex);

                    locals.FreeTempIndex(localIndex);
                }
            }
		internal static void AssertInstruction(Instruction actual, OpCode opCode, MemberReference expectedCtor)
		{
			Assert.AreEqual(opCode, actual.OpCode);
			MethodReference actualCtor = (MethodReference)actual.Operand;
			Assert.AreEqual(expectedCtor.DeclaringType.Name, actualCtor.DeclaringType.Name, opCode.ToString());
			Assert.AreEqual(expectedCtor, actualCtor.Resolve(), opCode.ToString());
		}
		private static bool IsMethodCallOnList(Instruction candidate)
		{
			if (candidate.OpCode != OpCodes.Call && candidate.OpCode != OpCodes.Callvirt) return false;

			MethodDefinition callee = ((MethodReference)candidate.Operand).Resolve();
			return callee.DeclaringType.Resolve().FullName == callee.DeclaringType.Module.Import(typeof(List<>)).FullName;
		}
Esempio n. 6
0
 public override void VisitInstruction(Instruction instr)
 {
   /*
   if (instr.Operand is TypeReference)
   {
     _modelCreator.UseType(((TypeReference)instr.Operand).ToTypeKey());
   }
   if (instr.Operand is FieldReference)
   {
     TypeKey typeKey = ((FieldReference)instr.Operand).FieldType.ToTypeKey();
     if (typeKey != null)
     {
       _modelCreator.UseType(typeKey);
     }
   }
   */
   if (instr.Operand is MethodReference)
   {
     _modelCreator.UseType(((MethodReference)instr.Operand).DeclaringType.ToTypeKey());
     _modelCreator.UseMethod(((MethodReference)instr.Operand).ToMethodKey());
   }
   if (instr.Operand is PropertyReference)
   {
     _modelCreator.UseType(((PropertyReference)instr.Operand).DeclaringType.ToTypeKey());
     _modelCreator.UseProperty(((PropertyReference)instr.Operand).ToPropertyKey());
   }
 }
 public InvokeMethodReplacement(Instruction executeOriginalInstructions, VariableDefinition methodReplacementProvider, VariableDefinition classMethodReplacementProvider, VariableDefinition invocationInfo)
 {
     _executeOriginalInstructions = executeOriginalInstructions;
     _methodReplacementProvider = methodReplacementProvider;
     _classMethodReplacementProvider = classMethodReplacementProvider;
     _invocationInfo = invocationInfo;
 }
        public CompiledString(MethodDefinition method, Instruction instruction)
        {
            Method = method;
            Instruction = instruction;

            OriginalValue = Value;
        }
Esempio n. 9
0
        /// <summary>
        /// Gets the instructions that generate the arguments for the call in the given instructions.
        /// </summary>
        public static Instruction[] GetCallArguments(this Instruction call, ILSequence sequence, bool includeThis)
        {
            var method = (MethodReference)call.Operand;
            var count = method.Parameters.Count;
            if (includeThis && method.HasThis)
            {
                count++;
            }
            var result = new Instruction[count];

            var current = call;
            var height = count;
            for (int i = count - 1; i >= 0; i--)
            {
                // Look for the starting instruction where stack height is i
                while (result[i] == null)
                {
                    var prevIndex = sequence.IndexOf(current);
                    var prev = (prevIndex >= 1) ? sequence[prevIndex - 1] : null;
                    if (prev == null)
                        throw new ArgumentException(string.Format("Cannot find arguments for call to {0}", method));
                    height -= prev.GetPushDelta();
                    if (height == i)
                        result[i] = prev;
                    height += prev.GetPopDelta(0, true);
                    current = prev;
                }
            }

            return result;
        }
Esempio n. 10
0
 protected override int _Pushes(Instruction i)
 {
     MethodReference method = (MethodReference)i.Operand;
     if (method.ReturnType == null)
         return 0;
     return 1;
 }
		private static int CountElementsInTheStack (MethodDefinition method, Instruction start, Instruction end)
		{
			Instruction current = start;
			int counter = 0;
			bool newarrDetected = false;
			while (end != current) {
				if (newarrDetected) {
					//Count only the stelem instructions if
					//there are a newarr instruction.
					if (current.OpCode == OpCodes.Stelem_Ref)
						counter++;
				}
				else {
					//Count with the stack
					counter += current.GetPushCount ();
					counter -= current.GetPopCount (method);
				}
				//If there are a newarr we need an special
				//behaviour
				if (current.OpCode == OpCodes.Newarr) {
					newarrDetected = true;
					counter = 0;
				}
				current = current.Next;
			}
			return counter;
		}
Esempio n. 12
0
 public static void InsertFront(this ILProcessor processor, Instruction instr)
 {
     if (processor.Body.Instructions.Count <= 0)
         processor.Append(instr);
     else
         processor.InsertBefore(processor.Body.Instructions[0], instr);
 }
Esempio n. 13
0
 protected override int _Pops(Instruction i, int stackSize)
 {
     // Check i.Operand?
     if (stackSize == 1)
         return 1;
     return 0;
 }
Esempio n. 14
0
		public object ReadOperand(Instruction instruction)
		{
			while (instruction.Operand is Instruction)
				instruction = (Instruction)instruction.Operand;

			return instruction.Operand;
		}
        private bool TryGetInstruction(List<ILRange> ilRanges, OpCode opCode, out Instruction instruction) {
            int fromOffset = 0;
            int toOffset = 0;

            if (ilRanges == null || ilRanges.Count == 0) {
                instruction = null;
                return false;
            }

            fromOffset = ilRanges[0].From;
            toOffset = ilRanges[0].To;
            instruction = InstructionAt(fromOffset);

            do {
                if (instruction.OpCode == opCode) {
                    return true;
                }

                instruction = instruction.Next;
                fromOffset = instruction.Offset;
            }
            while (fromOffset != toOffset);

            return instruction.OpCode == opCode;
        }
Esempio n. 16
0
        public void Store(Code op, Mono.Cecil.Cil.Instruction inst)
        {
            TypeCode elemType;

            switch (op)
            {
            case Code.Stelem_Ref:
            case Code.Stelem_Any:

                Store(null, null);
                return;

            case Code.Stelem_I1:                        elemType = TypeCode.Byte;   break;

            case Code.Stelem_I2:                        elemType = TypeCode.Int16;  break;

            case Code.Stelem_I4:                        elemType = TypeCode.Int32;  break;

            case Code.Stelem_I8:
            case Code.Stelem_I:    elemType = TypeCode.Int64;  break;

            case Code.Stelem_R4:                        elemType = TypeCode.Single; break;

            case Code.Stelem_R8:                        elemType = TypeCode.Double; break;

            default:                                    throw new InvalidProgramException();
            }

            Store(CilType.From(new JavaType(elemType, 0, null)), inst);
        }
Esempio n. 17
0
        private static IEnumerable<Instruction> NextInstructions(Instruction v)
        {
            var fc = v.OpCode.FlowControl;
            switch (fc)
            {
                case FlowControl.Next:
                case FlowControl.Call: // stay within the method
                    yield return v.Next;
                    break;

                case FlowControl.Return:
                    yield break;

                case FlowControl.Cond_Branch:
                    yield return v.Next;
                    if (v.Operand is Instruction[])
                    {
                        // switch statement
                        foreach (var i in (Instruction[])v.Operand)
                            yield return i;
                    }
                    else
                        yield return (Instruction)v.Operand;
                    break;

                case FlowControl.Branch:
                    yield return (Instruction)v.Operand;
                    break;

                default:
                    throw new NotImplementedException(fc.ToString());
            }
        }
Esempio n. 18
0
		public StackAnalysisResult(Instruction consumer, int offset, bool match, int stackHeight)
		{
			_consumer = consumer;
			_offset = offset;
			_match = match;
			_stackHeight = stackHeight;
		}
Esempio n. 19
0
        public void Append(Instruction instruction)
        {
            if (instruction == null)
                throw new ArgumentNullException ("instruction");

            instructions.Add (instruction);
        }
Esempio n. 20
0
		// look for a virtual call to a specific method
		static bool IsCallVirt (Instruction ins, string typeName, string methodName)
		{
			if (ins.OpCode.Code != Code.Callvirt)
				return false;
			MethodReference mr = (ins.Operand as MethodReference);
			return ((mr != null) && (mr.Name == methodName) && (mr.DeclaringType.FullName == typeName));
		}
 internal PrimitiveEmitter(PrimitiveExpression primitiveExpression, ILGenerator ilGenerator, IOpCodeIndexer instructionsIndexer)
     : base(ilGenerator, instructionsIndexer)
 {
     PrimitiveExpression = primitiveExpression;
     Type = PrimitiveExpression.Value.GetType();
     PrimitiveInstruction = InstructionsIndexer.GetInstruction(PrimitiveExpression);
 }
Esempio n. 22
0
 public static void ChangeThreeToSeven(Instruction i)
 {
     if (i.OpCode.Code == Code.Ldc_I4_3 && i.Previous.OpCode == OpCodes.Stloc_S && i.Next.OpCode == OpCodes.Stloc_S)
     {
         i.OpCode = OpCodes.Ldc_I4_7;
     }
 }
Esempio n. 23
0
 // Sets pops to -1 if the stack is supposed to be cleared
 public static void calculateStackUsage(Instruction instr, bool methodHasReturnValue, out int pushes, out int pops)
 {
     if (instr.OpCode.FlowControl == FlowControl.Call)
         calculateStackUsage_call(instr, out pushes, out pops);
     else
         calculateStackUsage_nonCall(instr, methodHasReturnValue, out pushes, out pops);
 }
Esempio n. 24
0
        public IEnumerable <ValidationResult> Validate(Mono.Cecil.Cil.Instruction instruction, MethodDefinition method)
        {
            if (!(instruction.Operand is MemberReference reference))
            {
                return(Enumerable.Empty <ValidationResult>());
            }

            if (reference is MethodReference methodReference)
            {
                var validationResults = new List <ValidationResult>();
                validationResults.AddRange(this.ValidateReference(method, methodReference.DeclaringType, methodReference.Name));
                validationResults.AddRange(this.ValidateReference(method, methodReference.ReturnType));

                return(validationResults);
            }

            if (reference is FieldReference fieldReference)
            {
                var validationResults = new List <ValidationResult>();
                validationResults.AddRange(this.ValidateReference(method, fieldReference.DeclaringType, fieldReference.Name));
                validationResults.AddRange(this.ValidateReference(method, fieldReference.FieldType));

                return(validationResults);
            }

            if (reference is TypeReference typeReference)
            {
                return(this.ValidateReference(method, typeReference));
            }

            return(Enumerable.Empty <ValidationResult>());
        }
		private static bool IsCastTo(TypeDefinition castTarget, Instruction instruction)
		{
			if (instruction.OpCode != OpCodes.Castclass) return false;

			TypeReference typeReference = (TypeReference)instruction.Operand;
			return typeReference.Resolve() == castTarget;
		}
 private Instruction EmitCodeInit(TypeReference role, Instruction instructionBeforeInit, ILProcessor il)
 {
     var current = instructionBeforeInit;
       current = InsertAfter(il, current, il.Create(OpCodes.Ldarg_0));
       current = InsertAfter(il, current, il.Create(OpCodes.Call, ResolveInitReference(role)));
       return current;
 }
		private static bool IsInstantiationOf(TypeDefinition definition, Instruction candidate)
		{ 
			if (candidate.OpCode != OpCodes.Newobj) return false;

			MethodReference ctor = (MethodReference) candidate.Operand;
			return ctor.DeclaringType.Resolve() == definition;
		}
Esempio n. 28
0
 public static void ChangeFoursToEights(Instruction i)
 {
     if (i.OpCode.Code == Code.Ldc_I4_4)
     {
         i.OpCode = OpCodes.Ldc_I4_8;
     }
 }
Esempio n. 29
0
        public static void CompareEq(JavaType stackTop, JavaType stackTop2,
                                     Mono.Cecil.Cil.Instruction cilInst, JavaCode code)
        {
            if (stackTop.Equals(SpanType) &&
                (stackTop2.PrimitiveType == TypeCode.Int64 ||
                 stackTop2.PrimitiveType == TypeCode.UInt64))
            {
                // compare Span with long
                throw new InvalidProgramException();
            }

            if (stackTop2.Equals(SpanType) &&
                (stackTop.PrimitiveType == TypeCode.Int64 ||
                 stackTop.PrimitiveType == TypeCode.UInt64))
            {
                if (cilInst.Previous == null ||
                    cilInst.Previous.OpCode.Code != Code.Conv_U ||
                    cilInst.Previous.Previous == null ||
                    cilInst.Previous.Previous.OpCode.Code != Code.Ldc_I4_0)
                {
                    // make sure the program is comparing the span address against
                    // a zero value, which we can convert to a null reference.
                    //      ldarg.1 (span argument)
                    //      ldc.i4.0
                    //      conv.u
                    //      bne.un label
                    throw new InvalidProgramException();
                }
                // compare long with Span
                code.NewInstruction(0x58 /* pop2 */, null, null);
                code.NewInstruction(0x01 /* aconst_null */, null, null);
            }
        }
Esempio n. 30
0
		/// <summary>
		/// Replaces instruction references (ie if, try) to a new instruction target.
		/// This is useful if you are injecting new code before a section of code that is already
		/// the receiver of a try/if block.
		/// </summary>
		/// <param name="current">The original instruction</param>
		/// <param name="newTarget">The new instruction that will receive the transfer</param>
		/// <param name="originalMethod">The original method that is used to search for transfers</param>
		public static void ReplaceTransfer(this Instruction current, Instruction newTarget, MethodDefinition originalMethod)
		{
			//If a method has a body then check the instruction targets & exceptions
			if (originalMethod.HasBody)
			{
				//Replaces instruction references from the old instruction to the new instruction
				foreach (var ins in originalMethod.Body.Instructions.Where(x => x.Operand == current))
					ins.Operand = newTarget;

				//If there are exception handlers, it's possible that they will also need to be switched over
				if (originalMethod.Body.HasExceptionHandlers)
				{
					foreach (var handler in originalMethod.Body.ExceptionHandlers)
					{
						if (handler.FilterStart == current) handler.FilterStart = newTarget;
						if (handler.HandlerEnd == current) handler.HandlerEnd = newTarget;
						if (handler.HandlerStart == current) handler.HandlerStart = newTarget;
						if (handler.TryEnd == current) handler.TryEnd = newTarget;
						if (handler.TryStart == current) handler.TryStart = newTarget;
					}
				}

				//Update the new target to take the old targets place
				newTarget.Offset = current.Offset;
				newTarget.SequencePoint = current.SequencePoint;
				newTarget.Offset++; //TODO: spend some time to figure out why this is incrementing
			}
		}
Esempio n. 31
0
        //public OpCode opCode;
        //public static Queue<Instruction> LoadParameter(MethodCallStackFrame closure, int index)
        //{
        //    //var loadParameter = new Queue<Instruction>();
        //    //Instruction current;
        //    ////if(index == 0)
        //    ////    current = closure.thisLoad;
        //    ////else
        //    //    current = closure.parameters[index - 1];
        //    //while (current != closure.parameters[index])
        //    //{
        //    //    current = current.Next;
        //    //    loadParameter.Enqueue(current);
        //    //}
        //    //return loadParameter;
        //}
        public static MethodCallStackFrame GetMethodCallStackFrame(Instruction methodCall)
        {
            var methodReference = methodCall.Operand as MethodReference;
            var parametersCount = methodReference.Parameters.Count + (methodReference.HasThis ? 1 : 0);

            var stackFrame = new MethodCallStackFrame()
            {
                methodReference = methodReference,
                methodCall = methodCall,
                parameters = new Instruction[parametersCount]
            };

            var instructionsCoutner = parametersCount;
            var currentParameter = parametersCount - 1; // zero based
            var currentInstruction = methodCall;

            while(instructionsCoutner != 0)
            {
                currentInstruction = currentInstruction.Previous;

                instructionsCoutner -= GetStackModifier(currentInstruction);

                if (instructionsCoutner == currentParameter)
                    stackFrame.parameters[currentParameter--] = currentInstruction;
            }
            return stackFrame;
        }
Esempio n. 32
0
 public void OnInstruction(Mono.Cecil.Cil.Instruction i)
 {
     foreach (AbstractCollector col in m_collectionTable.Values)
     {
         col.OnInstruction(i);
     }
 }
		static bool IsFloatingPointArguments (Instruction ins, MethodDefinition method)
		{
			TypeReference tr = ins.GetOperandType (method);
			if (tr == null)
				return false;
			return tr.IsFloatingPoint ();
		}
 public SwitchRunnable(BlockDecomposer block, IList<int> cyclomaticComplexity, Instruction defaultCase, params Instruction[] cases)
 {
     this.block = block;
     this.cyclomaticComplexity = cyclomaticComplexity;
     this.defaultCase = defaultCase;
     this.cases = cases;
 }
        /// <summary>
        /// Performs the optimization starting at the current instruction.
        /// </summary>
        /// <param name="instruction">The instruction to target.</param>
        /// <param name="worker">The worker for optimization actions.</param>
        public override void OptimizeInstruction(Instruction instruction, OptimizationWorker worker)
        {
            // TODO: allow arguments
            // TODO: allow return values
            // TODO: allow generic methods
            // TODO: allow non-static methods
            var opCode = instruction.OpCode;
            if (opCode.FlowControl != FlowControl.Call)
            {
                return;
            }

            var methodRef = (MethodReference) instruction.Operand;
            var typeRef = methodRef.DeclaringType;
            var module = typeRef.Module;

            var type = module.Types[typeRef.FullName];
            if (type == null)
            {
                return;
            }

            var method = type.Methods.GetMethod(methodRef.Name, methodRef.Parameters);
            bool shouldInlineMethod;
            if (!this.shouldInline.TryGetValue(method, out shouldInlineMethod))
            {
                shouldInlineMethod = this.configuration.ShouldInline(method);
                this.shouldInline[method] = shouldInlineMethod;
            }

            if (shouldInlineMethod)
            {
                InlineMethod(instruction, worker, method);
            }
        }
		public static void Dispatch (Instruction instruction, IInstructionVisitor visitor)
		{
			switch (instruction.OpCode.Code) {
<%
	for instr in Instructions:
		for opcode in instr.OpCodes:
%>			case Code.${opcode}:
Esempio n. 37
0
 public static string InstructionText(Instruction inst)
 {
     if (inst.Operand is Mono.Cecil.Cil.Instruction)
     {
         Mono.Cecil.Cil.Instruction instruccion = (Instruction)inst.Operand;
         return(string.Format("{0} {1}", inst.OpCode.ToString(), instruccion.Offset.ToString()));
     }
     else if (inst.Operand is string)
     {
         return(string.Format("{0} \"{1}\"", inst.OpCode.ToString(), inst.Operand.ToString()));
     }
     else if (inst.Operand is MethodReference)
     {
         MethodReference metodo = (MethodReference)inst.Operand;
         return(inst.OpCode.ToString() + " " + metodo.ToString());
     }
     else if (inst.Operand != null)
     {
         return(inst.OpCode.ToString() + " " + inst.Operand.ToString());
     }
     else
     {
         return(inst.OpCode.ToString());
     }
 }
Esempio n. 38
0
        private static int GetOperatorValue(Mono.Cecil.Cil.Instruction parameterInstruction)
        {
            switch (parameterInstruction.OpCode.ToString())
            {
            case "ldc.i4.0":
                return(0);

            case "ldc.i4.1":
                return(1);

            case "ldc.i4.2":
                return(2);

            case "ldc.i4.3":
                return(3);

            case "ldc.i4.4":
                return(4);

            case "ldc.i4.5":
                return(5);

            case "ldc.i4.6":
                return(7);

            case "ldc.i4.7":
                return(8);

            default:
                return(Convert.ToInt32(parameterInstruction.Operand));
            }
        }
Esempio n. 39
0
 public static void ChangeThreesToSevens(Instruction i)
 {
     if (i.OpCode.Code == Code.Ldc_I4_3)
     {
         i.OpCode = OpCodes.Ldc_I4_7;
     }
 }
Esempio n. 40
0
        public static void Switch(JavaCode code, Mono.Cecil.Cil.Instruction cilInst)
        {
            if (cilInst.Operand is Mono.Cecil.Cil.Instruction[] targets)
            {
                if ((targets.Length > Int32.MaxValue - 1) ||
                    cilInst.Next == null ||
                    (!code.StackMap.PopStack(CilMain.Where).IsIntLike))
                {
                    throw new InvalidProgramException();
                }

                ushort offset = (ushort)cilInst.Next.Offset;
                code.StackMap.SaveFrame(offset, true, CilMain.Where);

                int n        = targets.Length;
                var instdata = new int[3 + n];
                instdata[0] = offset;
                instdata[2] = n - 1;

                for (int i = 0; i < n; i++)
                {
                    offset = (ushort)targets[i].Offset;
                    code.StackMap.SaveFrame(offset, true, CilMain.Where);
                    instdata[i + 3] = offset;
                }

                code.NewInstruction(0xAA /* tableswitch */, null, instdata);
            }
        }
Esempio n. 41
0
        public static bool IsAndBeforeShift(Mono.Cecil.Cil.Instruction inst, JavaCode code)
        {
            // jvm shift instructions mask the shift count, so
            // eliminate AND-ing with 31 and 63 prior to a shift.

            // the input inst should point to the first of three
            // instructions, and here we check if the sequence is:
            // ldc_i4 31 or 63; and; shift

            // used by LoadConstant (see above), CodeNumber::Calculation

            var next1 = inst.Next;

            if (next1 != null && next1.OpCode.Code == Code.And)
            {
                var next2 = next1.Next;
                if (next2 != null && (next2.OpCode.Code == Code.Shl ||
                                      next2.OpCode.Code == Code.Shr ||
                                      next2.OpCode.Code == Code.Shr_Un))
                {
                    var stackArray = code.StackMap.StackArray();
                    if (stackArray.Length >= 2 &&
                        IsLoadConstant(inst) is int shiftMask &&
                        ((shiftMask == 31 &&
                          stackArray[0].Equals(JavaType.IntegerType)) ||
                         (shiftMask == 63 &&
                          stackArray[0].Equals(JavaType.LongType))))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        private static void CompileStoreLocalN(CInstruction instruction, List <string> imports, List <SectionEntry> code, int n)
        {
            // pop local N
            // Pop a value from stack into local variable n

            // addr=LCL+2
            // SP--
            // *addr=*SP
            throw new NotImplementedException();
        }
Esempio n. 43
0
        static byte TestEq(JavaCode code, JavaType stackTop, JavaType stackTop2,
                           Mono.Cecil.Cil.Instruction cilInst)
        {
            if (stackTop.IsReference || stackTop2.IsReference)
            {
                byte cmpOp = CodeSpan.CompareEq(stackTop, stackTop2, cilInst, code);
                if (cmpOp == 0)
                {
                    cmpOp = 0xA5; // if_acmpeq (reference)
                }
                return(cmpOp);
            }

            if (stackTop2.IsIntLike && (stackTop.PrimitiveType == TypeCode.Int32 ||
                                        stackTop.PrimitiveType == TypeCode.UInt32 ||
                                        stackTop.PrimitiveType == TypeCode.Int16 ||
                                        stackTop.PrimitiveType == TypeCode.UInt16 ||
                                        stackTop.PrimitiveType == TypeCode.SByte ||
                                        stackTop.PrimitiveType == TypeCode.Byte ||
                                        stackTop.PrimitiveType == TypeCode.Char ||
                                        stackTop.PrimitiveType == TypeCode.Boolean))
            {
                return(0x9F); // if_icmpeq
            }

            byte op;

            if ((stackTop.PrimitiveType == TypeCode.Int64 ||
                 stackTop.PrimitiveType == TypeCode.UInt64) &&
                (stackTop2.PrimitiveType == TypeCode.Int64 ||
                 stackTop2.PrimitiveType == TypeCode.UInt64))
            {
                op = 0x94; // lcmp (long)
            }

            else if (stackTop.PrimitiveType == TypeCode.Single &&
                     stackTop2.PrimitiveType == TypeCode.Single)
            {
                op = 0x95; // fcmpl (float)
            }

            else if (stackTop.PrimitiveType == TypeCode.Double &&
                     stackTop2.PrimitiveType == TypeCode.Double)
            {
                op = 0x97; // dcmpl (double)
            }

            else
            {
                throw new Exception($"incompatible types '{stackTop}' and '{stackTop2}'");
            }

            code.NewInstruction(op, null, null);
            return(0x99); // ifeq == zero
        }
        private static void Compile(CInstruction instruction, List <string> imports, List <SectionEntry> textSectionInstructions)
        {
            if (_compileInstructionActions.TryGetValue(instruction.OpCode.Code, out var compileAction))
            {
                textSectionInstructions.Add(new SectionLabel($"CIL_{instruction.Offset:X4}"));

                compileAction(instruction, imports, textSectionInstructions);
            }

            throw new NotSupportedException($"Unsupported op code {instruction.OpCode.Code} while compiling instruction: {instruction}");
        }
Esempio n. 45
0
        public IEnumerable <ValidationResult> Validate(Mono.Cecil.Cil.Instruction instruction, MethodDefinition method)
        {
            var errors = new List <FloatValidationResult>();

            if (IsFloat(instruction))
            {
                errors.Add(new FloatValidationResult(method));
            }

            return(errors);
        }
        public override bool MoveToNext(Navigator n)
        {
            bool result = false;
            InstructionDefinition instruction = Cast(n);

            if (instruction.Next != null)
            {
                n.Current = instruction.Next;
                result    = true;
            }
            return(result);
        }
Esempio n. 47
0
        public static bool IsMethodCall(Mono.Cecil.Cil.Instruction i)
        {
            if (i.Operand is Mono.Cecil.CallSite || i.Operand is Mono.Cecil.FieldReference)
                return false;

            return i.OpCode == Mono.Cecil.Cil.OpCodes.Call ||
                   i.OpCode == Mono.Cecil.Cil.OpCodes.Calli ||
                   i.OpCode == Mono.Cecil.Cil.OpCodes.Callvirt ||
                // Constructor
                   i.OpCode == Mono.Cecil.Cil.OpCodes.Newobj;
                    
        }
Esempio n. 48
0
        static public int Add(this MethodBody body, Mono.Cecil.Cil.Instruction instruction)
        {
            body.Instructions.Add(instruction);
            var _branch = Branch.Query(body);

            if (_branch == null)
            {
                return(body.Instructions.Count - 1);
            }
            _branch.Finialize(instruction);
            return(body.Instructions.Count - 1);
        }
Esempio n. 49
0
        public static void Straight(JavaCode code, Code cilOp, CodeLocals locals,
                                    Mono.Cecil.Cil.Instruction cilInst)
        {
            //
            // a straight branch maps to the corresponding compare logic
            // (beq = ceq, bgt = cgt, blt = clt), plus logic for brtrue.
            //

            byte   op;
            ushort nextInstOffset = 0;

            if (cilOp == Code.Br || cilOp == Code.Br_S)
            {
                if (cilInst.Operand is Mono.Cecil.Cil.Instruction inst)
                {
                    if (inst == cilInst.Next)
                    {
                        op = 0x00; // nop
                    }
                    else
                    {
                        op = 0xA7; // goto
                        if (cilInst.Next != null)
                        {
                            nextInstOffset = (ushort)cilInst.Next.Offset;
                        }
                    }
                }
                else
                {
                    throw new InvalidProgramException();
                }
            }
            else
            {
                var stackTop = code.StackMap.PopStack(CilMain.Where);
                op = Common(code, cilOp, cilInst, stackTop);
            }

            Finish(code, locals, cilInst, op);

            if (nextInstOffset != 0)
            {
                if (!code.StackMap.LoadFrame(nextInstOffset, true, null))
                {
                    if (op == 0xA7 /* goto */)
                    {
                        locals.TrackUnconditionalBranch(cilInst);
                    }
                }
            }
        }
Esempio n. 50
0
 private void InsertAndBoxConstant(Injector injector, object constant, TypeReference type, TypeReference boxType = null)
 {
     if (type.IsType <string>())
     {
         injector.Insert(OpCodes.Ldstr, (string)constant);
     }
     else if (type.IsType <int>())
     {
         injector.Insert(OpCodes.Ldc_I4, (int)constant);
     }
     else if (type.IsType <long>())
     {
         injector.Insert(OpCodes.Ldc_I8, (long)constant);
     }
     else if (type.IsType <double>())
     {
         injector.Insert(OpCodes.Ldc_R8, (double)constant);
     }
     else if (type.IsType <float>())
     {
         injector.Insert(OpCodes.Ldc_R4, (float)constant);
     }
     else if (type.IsType <short>())
     {
         injector.Insert(OpCodes.Ldc_I4, (short)constant);
     }
     else if (type.IsType <byte>())
     {
         injector.Insert(OpCodes.Ldc_I4, (byte)constant);
     }
     else if (type.IsType <uint>())
     {
         injector.Insert(OpCodes.Ldc_I4, (int)(uint)constant);
     }
     else if (type.IsType <ulong>())
     {
         injector.Insert(OpCodes.Ldc_I8, (long)(ulong)constant);
     }
     else if (type.IsType <ushort>())
     {
         injector.Insert(OpCodes.Ldc_I4, (ushort)constant);
     }
     else if (type.IsType <sbyte>())
     {
         injector.Insert(OpCodes.Ldc_I4, (sbyte)constant);
     }
     if (boxType != null)
     {
         injector.Insert(Instruction.Create(OpCodes.Box, boxType));
     }
     Logger.Warning($"Unknown constant type {constant.GetType().FullName}");
 }
Esempio n. 51
0
File: cfg.cs Progetto: baufeng/Campy
        public Vertex FindEntry(Mono.Cecil.Cil.Instruction inst)
        {
            Vertex result = null;

            foreach (CFG.Vertex node in this.Vertices)
            {
                if (node.Instructions.First().Instruction == inst)
                {
                    return(node);
                }
            }
            return(result);
        }
Esempio n. 52
0
        static byte Common(JavaCode code, Code cilOp, Mono.Cecil.Cil.Instruction cilInst, JavaType stackTop)
        {
            if (cilInst.Operand is Mono.Cecil.Cil.Instruction inst)
            {
                bool branchToNext = (inst == cilInst.Next);

                if (cilOp == Code.Brtrue || cilOp == Code.Brtrue_S)
                {
                    if (branchToNext)
                    {
                        return(PopOpCode(stackTop));
                    }
                    else
                    {
                        return(TestBool(code, stackTop));
                    }
                }

                // all other conditionals pop a second value off the stack
                var stackTop2 = code.StackMap.PopStack(CilMain.Where);
                if (branchToNext)
                {
                    code.NewInstruction(PopOpCode(stackTop2), null, null);
                    return(PopOpCode(stackTop));
                }

                if (cilOp == Code.Beq || cilOp == Code.Beq_S)
                {
                    return(TestEq(code, stackTop, stackTop2, cilInst));
                }
                else
                {
                    return(TestGtLt(code, stackTop, stackTop2,
                                    /* if greater than */ (cilOp == Code.Bgt ||
                                                           /* (vs less than) */ cilOp == Code.Bgt_S ||
                                                           cilOp == Code.Bgt_Un ||
                                                           cilOp == Code.Bgt_Un_S),
                                    /* if unsigned */ (cilOp == Code.Bgt_Un ||
                                                       /* or unordered */ cilOp == Code.Bgt_Un_S ||
                                                       cilOp == Code.Blt_Un ||
                                                       cilOp == Code.Blt_Un_S)));
                }
            }
            else
            {
                throw new InvalidProgramException();
            }

            byte PopOpCode(JavaType forType) => (byte)(0x56 + forType.Category);
        }
Esempio n. 53
0
 bool InstructionIsFontSizeConverterCtor(MethodDefinition methodDef, Mono.Cecil.Cil.Instruction instruction)
 {
     if (instruction.OpCode != OpCodes.Newobj)
     {
         return(false);
     }
     if (!(instruction.Operand is MethodReference methodRef))
     {
         return(false);
     }
     if (!Build.Tasks.TypeRefComparer.Default.Equals(methodRef.DeclaringType, methodDef.Module.ImportReference(typeof(Microsoft.Maui.Controls.FontSizeConverter))))
     {
         return(false);
     }
     return(true);
 }
Esempio n. 54
0
        /// <summary>
        /// Reads an instruction operand by recursive calling until non-instruction
        /// operand is found
        /// </summary>
        /// <param name="instruction">An instruction with operand</param>
        /// <returns>An instruction operand</returns>
        public object ReadOperand(Mono.Cecil.Cil.Instruction instruction)
        {
            if (instruction.Operand == null)
            {
                return(null);
            }

            var nextInstruction = instruction.Operand as Mono.Cecil.Cil.Instruction;

            if (nextInstruction != null)
            {
                return(ReadOperand(nextInstruction));
            }

            return(instruction.Operand);
        }
Esempio n. 55
0
 bool InstructionIsOnPlatformExtensionCtor(MethodDefinition methodDef, Mono.Cecil.Cil.Instruction instruction)
 {
     if (instruction.OpCode != OpCodes.Newobj)
     {
         return(false);
     }
     if (!(instruction.Operand is MethodReference methodRef))
     {
         return(false);
     }
     if (!Build.Tasks.TypeRefComparer.Default.Equals(methodRef.DeclaringType, methodDef.Module.ImportReference(typeof(OnPlatformExtension))))
     {
         return(false);
     }
     return(true);
 }
Esempio n. 56
0
        static void Finish(JavaCode code, CodeLocals locals,
                           Mono.Cecil.Cil.Instruction cilInst, byte op)
        {
            var inst = (Mono.Cecil.Cil.Instruction)cilInst.Operand;

            bool isNop;

            if (op == 0x00 || op == 0x57 || op == 0x58) // nop, pop, pop2
            {
                isNop = true;
            }
            else
            {
                isNop = false;
                int diff = cilInst.Offset - inst.Offset;
                if (diff < -0x2000 || diff > 0x2000)
                {
                    // branch instructions use 16-bits for the signed offset.
                    // for farther branches, we have to negate the condition,
                    // and insert a 32-bit 'goto_w' instruction.

                    if (cilInst.Next != null)
                    {
                        op = NegateCondition(op);
                        var nextOffset = (ushort)cilInst.Next.Offset;
                        code.NewInstruction(op, null, nextOffset);
                        code.StackMap.SaveFrame(nextOffset, true, CilMain.Where);
                    }

                    op = 0xC8;
                }
            }

            code.NewInstruction(op, null, (ushort)inst.Offset);

            if (!isNop)  // no stack frame for 'nop' or 'pop'
            {
                var resetLocals =
                    code.StackMap.SaveFrame((ushort)inst.Offset, true, CilMain.Where);

                if (resetLocals != null)
                {
                    ResetLocalsOutOfScope(code.StackMap, locals, resetLocals, cilInst, inst);
                }
            }
        }
        private static void CompileLoadLocalN(CInstruction instruction, List <string> imports, List <SectionEntry> code, int n)
        {
            // push local N
            // Load local variable of index n onto stack
            // PUSH constant 17
            // @17 // D=17
            // D=A
            // @SP // *SP=D
            // A=M
            // M=D
            // @SP
            // M=M+1

            // mov rax, SP
            // add rsp, 1
            throw new NotImplementedException();
        }
Esempio n. 58
0
        private static bool AnalyzeMethodFieldSets(MethodDefinition methodDefinition, XElement entity, XElement newMethodNode)
        {
            bool result = false;

            Mono.Cecil.Cil.MethodBody body = methodDefinition.Body;
            if (null != body)
            {
                foreach (Instruction itemInstruction in body.Instructions)
                {
                    if (itemInstruction.OpCode.Name.StartsWith("stfld") || itemInstruction.OpCode.Name.StartsWith("stsfld"))
                    {
                        Mono.Cecil.Cil.Instruction methodInstruction = itemInstruction as Mono.Cecil.Cil.Instruction;
                        Mono.Cecil.FieldDefinition fieldDefinition   = methodInstruction.Operand as Mono.Cecil.FieldDefinition;
                        if (fieldDefinition != null && fieldDefinition.FieldType.IsValueType)
                        {
                            Mono.Cecil.Cil.Instruction paramInstruction = GetParameterInstructionForField(methodInstruction);
                            if (null != paramInstruction)
                            {
                                bool sucseed = false;
                                int  opValue = GetOperatorValue(paramInstruction, out sucseed);
                                if (sucseed)
                                {
                                    string[] supportByLibrary = _netOfficeSupportTable.GetEnumMemberSupport(fieldDefinition.FieldType.FullName, (int)opValue);
                                    if (null != supportByLibrary)
                                    {
                                        XElement newParameter  = new XElement("Field", new XAttribute("Name", fieldDefinition.Name));
                                        string   componentName = NetOfficeSupportTable.GetLibrary(fieldDefinition.FieldType.FullName);
                                        XElement supportByNode = new XElement("SupportByLibrary", new XAttribute("Api", componentName));
                                        string   memberName    = _netOfficeSupportTable.GetEnumMemberNameFromValue(fieldDefinition.FieldType.FullName, opValue);
                                        supportByNode.Add(new XAttribute("Name", fieldDefinition.FieldType + "." + memberName));
                                        foreach (string item in supportByLibrary)
                                        {
                                            supportByNode.Add(new XElement("Version", item));
                                        }
                                        newParameter.Add(supportByNode);
                                        newMethodNode.Element("FieldSets").Add(newParameter);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
Esempio n. 59
0
 public static int?IsLoadConstant(Mono.Cecil.Cil.Instruction inst)
 {
     if (inst != null)
     {
         var op   = inst.OpCode.Code;
         var data = inst.Operand;
         if (op == Code.Ldc_I4 && data is int intVal)
         {
             return(intVal);
         }
         if (op == Code.Ldc_I4_S && data is sbyte sbyteVal)
         {
             return(sbyteVal);
         }
     }
     return(null);
 }
Esempio n. 60
0
        public void Call(CilMethod method, Mono.Cecil.Cil.Instruction inst)
        {
            int numDims  = method.Parameters.Count;
            var elemType = method.DeclType;

            if (method.Name == "Get")
            {
                Deref(numDims);

                stackMap.PopStack(CilMain.Where);   // pop index
                stackMap.PopStack(CilMain.Where);   // pop array
                Load(null, elemType, inst);
            }

            else if (method.Name == "Set")
            {
                numDims--;          // last parameter is value
                if (numDims > 1)
                {
                    var valueType  = stackMap.PopStack(CilMain.Where);
                    int localIndex = locals.GetTempIndex(valueType);
                    code.NewInstruction(valueType.StoreOpcode, null, localIndex);

                    Deref(numDims);

                    code.NewInstruction(valueType.LoadOpcode, null, localIndex);
                    stackMap.PushStack(valueType);
                }

                Store(elemType);
            }

            else if (method.Name == "Address")
            {
                Deref(numDims);

                Address(elemType);
            }

            else
            {
                throw new InvalidProgramException();
            }
        }