Exemplo n.º 1
0
        private ILCode CreateCode(string moduleName, string typeName, AstNode exp)
        {
            if (Path.GetFileName(moduleName) != moduleName)
            {
                throw new Exception("can only output into current directory!");
            }

            var             name        = new AssemblyName(Path.GetFileNameWithoutExtension(moduleName));
            AssemblyBuilder asmb        = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save);
            ModuleBuilder   modb        = asmb.DefineDynamicModule(moduleName);
            TypeBuilder     typeBuilder = modb.DefineType(typeName);
            MethodBuilder   methMain    = typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void),
                                                                   Type.EmptyTypes);

            var ilcode = new ILCode {
                Type = typeBuilder, Method = methMain, Module = modb
            };

            init.CodeInfo = ilcode;
            init.GeneratePredifinedCode();

            TypeBuilder nested = AddFunctionMainToCode(ilcode, methMain);

            ilcode.Type = nested;

            ILCodeGenerator codeGenerator = new ILCodeGenerator(ilcode);

            //generacion de codigos
            exp.Accept(codeGenerator);
            ILGenerator il = methMain.GetILGenerator();

            il.Emit(OpCodes.Ret);

            nested.CreateType();
            typeBuilder.CreateType();
            modb.CreateGlobalFunctions();
            asmb.SetEntryPoint(methMain);
            asmb.Save(moduleName);

            return(ilcode);
        }
Exemplo n.º 2
0
        public static bool IsConvFromUnsigned(this ILCode self)
        {
            switch (self)
            {
            case ILCode.Conv_Ovf_I_Un:
            case ILCode.Conv_Ovf_I1_Un:
            case ILCode.Conv_Ovf_I2_Un:
            case ILCode.Conv_Ovf_I4_Un:
            case ILCode.Conv_Ovf_I8_Un:
            case ILCode.Conv_Ovf_U_Un:
            case ILCode.Conv_Ovf_U1_Un:
            case ILCode.Conv_Ovf_U2_Un:
            case ILCode.Conv_Ovf_U4_Un:
            case ILCode.Conv_Ovf_U8_Un:
            case ILCode.Conv_R_Un:
                return(Program.Unsigned);

            default:
                return(false);
            }
        }
Exemplo n.º 3
0
        public override string ToString()
        {
            var ret = new StringBuilder();

            ret.AppendFormat("{0}{1}(", ILCode.ToOpCode().Name, Type == null ? "" : ":" + Type.Value);
            if (Operand != null)
            {
                if (Operand is string)
                {
                    ASTConstant.EscapeString(ret, (string)Operand, true);
                }
                else if (Operand is IBasicBlock)
                {
                    ret.AppendFormat("Block_{0:x2}", ((IBasicBlock)Operand).Id);
                }
                else if (Operand is IBasicBlock[])
                {
                    var targets = ((IBasicBlock[])Operand).Select(block => string.Format("Block_{0:x2}", block.Id));
                    ret.AppendFormat("[{0}]", string.Join(", ", targets));
                }
                else
                {
                    ret.Append(Operand);
                }
                if (Arguments.Length > 0)
                {
                    ret.Append(";");
                }
            }
            for (int i = 0; i < Arguments.Length; i++)
            {
                if (i != 0)
                {
                    ret.Append(",");
                }
                ret.Append(Arguments[i]);
            }
            ret.Append(")");
            return(ret.ToString());
        }
Exemplo n.º 4
0
        private void CreateParams(ILCode code, bool isFunction, out Type returnType, out Type[] parameterTypes)
        {
            returnType = null;
            if (isFunction)
            {
                string typeCodeName = _functionInvocation.CurrentScope.GetTypeInfo(ReturnTypeId()).CodeName;
                returnType = code.DefinedType[typeCodeName];
            }

            parameterTypes = null;
            List <KeyValuePair <string, string> > ParameterList = GetParameterList();

            if (ParameterList != null)
            {
                parameterTypes = new Type[ParameterList.Count];
                for (int i = 0; i < ParameterList.Count; i++)
                {
                    string typeCodeName = _functionInvocation.CurrentScope.GetTypeInfo(ParameterList[i].Value).CodeName;
                    parameterTypes[i] = code.DefinedType[typeCodeName];
                }
            }
        }
Exemplo n.º 5
0
        private MethodBuilder GetMethod(string funCodeName, ILCode code)
        {
            //si esta definida la uso
            if (code.DefinedMethod.ContainsKey(funCodeName))
            {
                return(code.DefinedMethod[funCodeName]);
            }

            //sino no  esta definida creo su signatura.
            //este es el nombre de la clase que contiene a este funcion
            string parentWrapper = string.Format("Tg_{0}", FunctionParentCodeName());
            //obtengo el tipo de la clase
            var container = (TypeBuilder)code.DefinedType[parentWrapper];

            Type returnType;

            Type[] parameterTypes;
            //creo los paremtros de la funcion
            bool isFunction = !string.IsNullOrEmpty(ReturnTypeId());

            //creando los parametros y el tipo de retorno
            CreateParams(code, isFunction, out returnType, out parameterTypes);

            //creo la funcion como un metodo de instancia.
            MethodBuilder mBuilder = container.DefineMethod(FunctionCodeName(), MethodAttributes.Public, returnType,
                                                            parameterTypes);

            //adiciono la nueva funcion que he declarado
            code.DefinedMethod.Add(mBuilder.Name, mBuilder);

            //Tener en cuenta cuando se llame la funcion antes de ser declarada ,hay que annadir el metodo a su padre
            string       currentFunctionParent = _functionInvocation.CurrentScope.CurrentFunction.FunctionParent.CodeName;
            TypeCodeInfo typeCodeInfo          = code.GetWrapperAsociatteTo(currentFunctionParent);

            typeCodeInfo.AddMethod(mBuilder.Name, mBuilder);
            //typcodeindo

            return(mBuilder);
        }
Exemplo n.º 6
0
        //public static Dictionary<MethodBase, uint> MethodUIDs = new Dictionary<MethodBase, uint>();

        public OpMethod(ILCode aCode, int aPosition, int aNextPosition, MethodBase aValue, ExceptionHandlingClause aEhc)
            : base(aCode, aPosition, aNextPosition, aEhc)
        {
            Value     = aValue;
            MethodUID = 0;

            if (aValue.IsAbstract)
            {
                MethodUID = (uint)aValue.GetHashCode();

                /*
                 * if (MethodUIDs.ContainsKey(aValue))
                 * {
                 *  MethodUID = MethodUIDs[aValue];
                 * }
                 * else
                 * {
                 *  MethodUID = Counter++;
                 *  MethodUIDs.Add(aValue, MethodUID);
                 * }*/
            }
        }
Exemplo n.º 7
0
        public static bool IsUnconditionalControlFlow(this ILCode code)
        {
            switch (code)
            {
            case ILCode.Br:
            case ILCode.__Br_S:
            case ILCode.Leave:
            case ILCode.__Leave_S:
            case ILCode.Ret:
            case ILCode.Endfilter:
            case ILCode.Endfinally:
            case ILCode.Throw:
            case ILCode.Rethrow:
            case ILCode.LoopContinue:
            case ILCode.LoopOrSwitchBreak:
            case ILCode.YieldBreak:
                return(true);

            default:
                return(false);
            }
        }
Exemplo n.º 8
0
        public static bool IsLoadFromArray(this ILCode code)
        {
            switch (code)
            {
            case ILCode.Ldelem_Any:
            case ILCode.Ldelem_I:
            case ILCode.Ldelem_I1:
            case ILCode.Ldelem_I2:
            case ILCode.Ldelem_I4:
            case ILCode.Ldelem_I8:
            case ILCode.Ldelem_U1:
            case ILCode.Ldelem_U2:
            case ILCode.Ldelem_U4:
            case ILCode.Ldelem_R4:
            case ILCode.Ldelem_R8:
            case ILCode.Ldelem_Ref:
                return(true);

            default:
                return(false);
            }
        }
Exemplo n.º 9
0
        private static TypeBuilder AddFunctionMainToCode(ILCode code, MethodBuilder main)
        {
            code.DefinedMethod.Add(MainFunction, main);
            //crear lo que sera el wrapper a esta funcion
            string      currentWrapper = string.Format("Tg_{0}", MainFunction);
            TypeBuilder typeNested     = code.Type.DefineNestedType(currentWrapper,
                                                                    TypeAttributes.NestedPublic);

            //crear en la variable de instancia de la clase contenedora,pues el Let asume que la tiene creada.
            ILGenerator il = main.GetILGenerator();

            il.DeclareLocal(typeNested);

            //annadir a la clase code el tipo.
            code.DefinedType.Add(typeNested.Name, typeNested);
            //asociar el tipo wrapper al metodo
            code.AsociatteMethodToWrapper(MainFunction, currentWrapper);

            code.GetWrapperAsociatteTo(MainFunction);
            //PopulateNestedTypeWithVar(code, typeNested, typeCodeInfo);

            return(typeNested);
        }
Exemplo n.º 10
0
        private void code_OnBeginMethod_var(VarDeclarationAST varDecl, ILCode theCode, BeginMethodEventArgs e)
        {
            VarInfo varInfo = varDecl.CurrentScope.GetVarInfo(varDecl.Id);

            var isMyFunction = varDecl.CurrentScope.GetFunction(varInfo.FunctionNameParent).CodeName == e.FunctionCodeName;

            //it is true if the funcion (e.FunctionCodeName) is the same that the function that declares this variable.
            if (isMyFunction)
            {
                ILGenerator il = code.Method.GetILGenerator();
                //--->
                bool pushOnStack = code.PushOnStack;
                code.PushOnStack = true;

                string varCodeName = varInfo.CodeName;
                if (!varInfo.IsUsedForAnotherFunction)
                {
                    if (!varInfo.IsParameterFunction) //significa que es una variable local
                    {
                        varDecl.ExpressionValue.Accept(this);
                        il.Emit(OpCodes.Stloc, code.DefinedLocal[varCodeName].LocalIndex);
                    }
                }
                else
                {
                    if (!varInfo.IsParameterFunction) //significa que es un campo de la clase
                    {
                        //cargar la instancia de la clase contenedora que tengo como variable local
                        il.Emit(OpCodes.Ldloc_0);
                        varDecl.ExpressionValue.Accept(this);
                        il.Emit(OpCodes.Stfld, code.DefinedField[varCodeName]);
                    }
                }
                //<---
                code.PushOnStack = pushOnStack;
            }
        }
        private void GenerateCodeForLogicalExpression(ILCode code)
        {
            ILGenerator il = code.Method.GetILGenerator();
            //hacer el corto circuito.
            //---> me quedo con el valor
            bool pushOnStack = code.PushOnStack;

            Label result = il.DefineLabel();
            Label end    = il.DefineLabel();

            // cargar valor exp1
            code.PushOnStack = true;
            _binaryExpression.LeftExp.Accept(_codeGenerator);

            //poner el salto
            PushJump(code, result);

            //cargar valor expr2
            code.PushOnStack = true;
            _binaryExpression.RightExp.Accept(_codeGenerator);

            il.Emit(OpCodes.Br, end);

            il.MarkLabel(result);
            PushResult(code);
            il.MarkLabel(end);


            if (!pushOnStack)
            {
                il.Emit(OpCodes.Pop);
            }

            //<--- pongo el valor il
            code.PushOnStack = pushOnStack;
        }
Exemplo n.º 12
0
        private static void OrdFunction(string functionName, ILCode codeInfo)
        {
            TypeBuilder type = codeInfo.Type;
            //ord(s:string)
            MethodBuilder ord = type.DefineMethod(functionName, MethodAttributes.Static | MethodAttributes.Public,
                                                  typeof(int), new[] { typeof(string) });

            ILGenerator il = ord.GetILGenerator();
            //TODO: Esto fue cambiado
            LocalBuilder result     = il.DeclareLocal(typeof(int));
            Label        asciiValue = il.DefineLabel();
            Label        end        = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, typeof(string).GetMethod("IsNullOrEmpty"));

            il.Emit(OpCodes.Brfalse_S, asciiValue);
            il.Emit(OpCodes.Ldc_I4_M1);
            il.Emit(OpCodes.Stloc_0);

            il.Emit(OpCodes.Br_S, end);

            il.MarkLabel(asciiValue);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Callvirt, typeof(string).GetMethod("get_Chars", new[] { typeof(int) }));
            il.Emit(OpCodes.Conv_I1);
            il.Emit(OpCodes.Stloc_0);

            il.MarkLabel(end);

            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Ret);

            codeInfo.DefinedMethod.Add(functionName, ord);
        }
Exemplo n.º 13
0
        public static bool IsOvf(this ILCode self)
        {
            switch (self)
            {
            case ILCode.Conv_Ovf_I:
            case ILCode.Conv_Ovf_I_Un:
            case ILCode.Conv_Ovf_I1:
            case ILCode.Conv_Ovf_I1_Un:
            case ILCode.Conv_Ovf_I2:
            case ILCode.Conv_Ovf_I2_Un:
            case ILCode.Conv_Ovf_I4:
            case ILCode.Conv_Ovf_I4_Un:
            case ILCode.Conv_Ovf_I8:
            case ILCode.Conv_Ovf_I8_Un:
            case ILCode.Conv_Ovf_U:
            case ILCode.Conv_Ovf_U_Un:
            case ILCode.Conv_Ovf_U1:
            case ILCode.Conv_Ovf_U1_Un:
            case ILCode.Conv_Ovf_U2:
            case ILCode.Conv_Ovf_U2_Un:
            case ILCode.Conv_Ovf_U4:
            case ILCode.Conv_Ovf_U4_Un:
            case ILCode.Conv_Ovf_U8:
            case ILCode.Conv_Ovf_U8_Un:
            case ILCode.Add_Ovf:
            case ILCode.Add_Ovf_Un:
            case ILCode.Sub_Ovf:
            case ILCode.Sub_Ovf_Un:
            case ILCode.Mul_Ovf:
            case ILCode.Mul_Ovf_Un:
                return(Program.OverflowCheck);

            default:
                return(false);
            }
        }
Exemplo n.º 14
0
		ILExpression MakeLeftAssociativeShortCircuit(ILCode code, ILExpression left, ILExpression right)
		{
			// Assuming that the inputs are already left associative
			if (right.Match(code)) {
				// Find the leftmost logical expression
				ILExpression current = right;
				while(current.Arguments[0].Match(code))
					current = current.Arguments[0];
				current.Arguments[0] = new ILExpression(code, null, left, current.Arguments[0]);
				return right;
			} else {
				return new ILExpression(code, null, left, right);
			}
		}
Exemplo n.º 15
0
 internal OpField(ILCode aCode, int aPosition, int aNextPosition, FieldInfo aValue, ExceptionHandlingClause aEhc)
     : base(aCode, aPosition, aNextPosition, aEhc)
 {
     Value = aValue;
 }
Exemplo n.º 16
0
 public VariablePattern(ILCode code, bool b)
     : base(null)
 {
     this.code = code;
     this.b = b;
 }
Exemplo n.º 17
0
 public ILPattern(ILCode code, params Pattern[] arguments)
     : base(arguments)
 {
     this.code = code;
 }
Exemplo n.º 18
0
        /// <summary>
        /// 指令优化,合并指令
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static List <ILCode> MergeCodes(List <ILCode> input, List <string> locals = null, List <string> args = null)
        {
            List <ILCode> outPut  = new List <ILCode>();
            var           opSpeed = new List <string>(new string[] { "add", "sub", "mul", "div" });

            for (int i = 0; i < input.Count; i++)
            {
                var now = input[i];
                //if (now.OpCode == "nop")
                //{
                //    continue;
                //}
                if (i > 2 && i < input.Count - 2)
                {
                    var before2 = input[i - 1 - 1];
                    var before  = input[i - 1];
                    var next    = input[i + 1];
                    var newx2   = input[i + 1 + 1];
                    if (opSpeed.Contains(now.Op) && locals != null)
                    {
                        if (before2.Op == "ldc")
                        {
                            now.OpCode += "." + before2.OpArg0;
                        }
                        else if (before.Op == "ldc")
                        {
                            now.OpCode += "." + before.OpArg0;
                        }
                        else if (before2.Op == "ldloc")
                        {
                            now.OpCode += "." + locals[int.Parse(before2.OpArg0)];
                        }
                        else if (before.Op == "ldloc")
                        {
                            now.OpCode += "." + locals[int.Parse(before.OpArg0)];
                        }
                        else if (before2.Op == "ldarg")
                        {
                            now.OpCode += "." + args[int.Parse(before2.OpArg0)];
                        }
                        else if (before.Op == "ldarg")
                        {
                            now.OpCode += "." + args[int.Parse(before.OpArg0)];
                        }
                    }
                }
                if (i < input.Count - 2)
                {
                    var next  = input[i + 1];
                    var newx2 = input[i + 1 + 1];
#if SPEED
                    if (now.Op == "ldc" && next.Op == "stloc")
                    {
                        var opcode = new ILCode()
                        {
                            OpCode = "LdcStloc",
                            Arg0   = now.OpArg0,
                            Arg1   = now.OpArg1 == null ? now.Arg0 : now.OpArg1,
                            Arg2   = next.OpArg0,
                            Lable  = now.Lable,
                            Line   = now.Line + " " + next.Line
                        };
                        opcode.Op = opcode.OpCode;
                        i++;
                        outPut.Add(opcode);
                        continue;
                    }
                    if (now.Op == "ldloc" && next.Op == "ldloc")
                    {
                        var opcode = new ILCode()
                        {
                            OpCode = "ldlocldloc",
                            Arg0   = now.OpArg0,
                            Arg1   = next.OpArg0,
                            Lable  = now.Lable,
                            Line   = now.Line + " " + next.Line
                        };
                        i++;
                        outPut.Add(opcode);
                        continue;
                    }
#endif
                }

                outPut.Add(now);
            }

            return(outPut);
        }
Exemplo n.º 19
0
        public static bool Match(this ILNode node, ILCode code)
        {
            ILExpression expr = node as ILExpression;

            return(expr != null && expr.Prefixes == null && expr.Code == code);
        }
Exemplo n.º 20
0
		bool isMatchControlBr(ILCode c, int value)
		{
			switch (c) {
			case ILCode.__Beq_S:
			case ILCode.__Bge_S:
			case ILCode.__Bgt_S:
			case ILCode.__Ble_S:
			case ILCode.__Blt_S:
			case ILCode.__Bne_Un_S:
			case ILCode.__Bge_Un_S:
			case ILCode.__Bgt_Un_S:
			case ILCode.__Ble_Un_S:
			case ILCode.__Blt_Un_S:
			case ILCode.__Beq:
			case ILCode.__Bge:
			case ILCode.__Bgt:
			case ILCode.__Ble:
			case ILCode.__Blt:
			case ILCode.__Bne_Un:
			case ILCode.__Bge_Un:
			case ILCode.__Bgt_Un:
			case ILCode.__Ble_Un:
			case ILCode.__Blt_Un:
				break;

			case ILCode.__Brfalse_S:
			case ILCode.__Brfalse:
				return value == 0;
			case ILCode.__Brtrue_S:
			case ILCode.Brtrue:
				return value != 0;
			default:
				break;
			}

			return false;	
		}
Exemplo n.º 21
0
        ILExpression IntroducePostIncrementForInstanceFields(ILExpression expr)
        {
            // stfld(field, ldloc(instance), add(stloc(helperVar, ldfld(field, ldloc(instance))), ldc.i4(1)))
            // -> stloc(helperVar, postincrement(1, ldflda(field, ldloc(instance))))

            // Also works for array elements and pointers:

            // stelem.any(T, ldloc(instance), ldloc(pos), add(stloc(helperVar, ldelem.any(T, ldloc(instance), ldloc(pos))), ldc.i4(1)))
            // -> stloc(helperVar, postincrement(1, ldelema(ldloc(instance), ldloc(pos))))

            // stobj(T, ldloc(ptr), add(stloc(helperVar, ldobj(T, ldloc(ptr)), ldc.i4(1))))
            // -> stloc(helperVar, postIncrement(1, ldloc(ptr)))

            // callsetter(set_P, ldloc(instance), add(stloc(helperVar, callgetter(get_P, ldloc(instance))), ldc.i4(1)))
            // -> stloc(helperVar, postIncrement(1, propertyaddress. callgetter(get_P, ldloc(instance))))

            if (!(expr.Code == ILCode.Stfld || expr.Code.IsStoreToArray() || expr.Code == ILCode.Stobj || expr.Code == ILCode.CallSetter || expr.Code == ILCode.CallvirtSetter))
            {
                return(null);
            }

            // Test that all arguments except the last are ldloc (1 arg for fields and pointers, 2 args for arrays)
            for (int i = 0; i < expr.Arguments.Count - 1; i++)
            {
                if (expr.Arguments[i].Code != ILCode.Ldloc)
                {
                    return(null);
                }
            }

            ILExpression addExpr = expr.Arguments[expr.Arguments.Count - 1];
            int          incrementAmount;
            ILCode       incrementCode = GetIncrementCode(addExpr, out incrementAmount);
            ILVariable   helperVar;
            ILExpression initialValue;

            if (!(incrementAmount != 0 && addExpr.Arguments[0].Match(ILCode.Stloc, out helperVar, out initialValue)))
            {
                return(null);
            }

            if (expr.Code == ILCode.Stfld)
            {
                if (initialValue.Code != ILCode.Ldfld)
                {
                    return(null);
                }
                // There might be two different FieldReference instances, so we compare the field's signatures:
                FieldReference getField = (FieldReference)initialValue.Operand;
                FieldReference setField = (FieldReference)expr.Operand;
                if (!(TypeAnalysis.IsSameType(getField.DeclaringType, setField.DeclaringType) &&
                      getField.Name == setField.Name && TypeAnalysis.IsSameType(getField.FieldType, setField.FieldType)))
                {
                    return(null);
                }
            }
            else if (expr.Code == ILCode.Stobj)
            {
                if (!(initialValue.Code == ILCode.Ldobj && initialValue.Operand == expr.Operand))
                {
                    return(null);
                }
            }
            else if (expr.Code == ILCode.CallSetter)
            {
                if (!(initialValue.Code == ILCode.CallGetter && IsGetterSetterPair(initialValue.Operand, expr.Operand)))
                {
                    return(null);
                }
            }
            else if (expr.Code == ILCode.CallvirtSetter)
            {
                if (!(initialValue.Code == ILCode.CallvirtGetter && IsGetterSetterPair(initialValue.Operand, expr.Operand)))
                {
                    return(null);
                }
            }
            else
            {
                if (!initialValue.Code.IsLoadFromArray())
                {
                    return(null);
                }
            }
            Debug.Assert(expr.Arguments.Count - 1 == initialValue.Arguments.Count);
            for (int i = 0; i < initialValue.Arguments.Count; i++)
            {
                if (!initialValue.Arguments[i].MatchLdloc((ILVariable)expr.Arguments[i].Operand))
                {
                    return(null);
                }
            }

            ILExpression stloc = addExpr.Arguments[0];

            if (expr.Code == ILCode.Stobj)
            {
                stloc.Arguments[0] = new ILExpression(ILCode.PostIncrement, incrementAmount, initialValue.Arguments[0]);
            }
            else if (expr.Code == ILCode.CallSetter || expr.Code == ILCode.CallvirtSetter)
            {
                initialValue       = new ILExpression(ILCode.AddressOf, null, initialValue);
                stloc.Arguments[0] = new ILExpression(ILCode.PostIncrement, incrementAmount, initialValue);
            }
            else
            {
                stloc.Arguments[0] = new ILExpression(ILCode.PostIncrement, incrementAmount, initialValue);
                initialValue.Code  = (expr.Code == ILCode.Stfld ? ILCode.Ldflda : ILCode.Ldelema);
            }
            // TODO: ILRanges?

            return(stloc);
        }
Exemplo n.º 22
0
        static object InvokeNodeTranslator(ILCode code, object thisReference, object[] arguments)
        {
            MethodBase boundMethod = null;
            var methods = GetNodeTranslators(code);

            if (methods != null) {
                if (methods.Length > 1) {
                    var bindingFlags = System.Reflection.BindingFlags.Instance |
                                System.Reflection.BindingFlags.InvokeMethod |
                                System.Reflection.BindingFlags.NonPublic;

                    var binder = Type.DefaultBinder;
                    object state;

                    try {
                        boundMethod = binder.BindToMethod(
                            bindingFlags, methods, ref arguments,
                            null, null, null, out state
                        );
                    } catch (Exception exc) {
                        throw new Exception(String.Format(
                            "Failed to bind to translator method for ILCode.{0}. Had {1} options:{2}{3}",
                            code, methods.Length,
                            Environment.NewLine,
                            String.Join(Environment.NewLine, (from m in methods select m.ToString()).ToArray())
                        ), exc);
                    }
                } else {
                    boundMethod = methods[0];
                }
            }

            if (boundMethod == null) {
                throw new MissingMethodException(
                    String.Format("Could not find a node translator for the node type '{0}'.", code)
                );
            }

            return boundMethod.Invoke(thisReference, arguments);
        }
Exemplo n.º 23
0
        static System.Reflection.MethodInfo[] GetNodeTranslators(ILCode code)
        {
            return NodeTranslatorCache.GetOrCreate(
                code, () => {
                    var methodName = String.Format("Translate_{0}", code);
                    var bindingFlags = System.Reflection.BindingFlags.Instance |
                                System.Reflection.BindingFlags.InvokeMethod |
                                System.Reflection.BindingFlags.NonPublic;

                    var t = typeof(ILBlockTranslator);

                    var methods = t.GetMember(
                            methodName, MemberTypes.Method, bindingFlags
                        ).OfType<System.Reflection.MethodInfo>().ToArray();

                    if (methods.Length == 0) {
                        var alternateMethodName = methodName.Substring(0, methodName.LastIndexOf("_"));
                        methods = t.GetMember(
                                alternateMethodName, MemberTypes.Method, bindingFlags
                            ).OfType<System.Reflection.MethodInfo>().ToArray();
                    }

                    if (methods.Length == 0)
                        return null;

                    return methods;
                }
            );
        }
Exemplo n.º 24
0
		public static void ExpandMacro(ref ILCode code, ref object operand, MethodBody methodBody)
		{
			switch (code) {
					case ILCode.__Ldarg_0: 		code = ILCode.Ldarg; operand = methodBody.GetParameter(0); break;
					case ILCode.__Ldarg_1: 		code = ILCode.Ldarg; operand = methodBody.GetParameter(1); break;
					case ILCode.__Ldarg_2: 		code = ILCode.Ldarg; operand = methodBody.GetParameter(2); break;
					case ILCode.__Ldarg_3: 		code = ILCode.Ldarg; operand = methodBody.GetParameter(3); break;
					case ILCode.__Ldloc_0: 		code = ILCode.Ldloc; operand = methodBody.Variables[0]; break;
					case ILCode.__Ldloc_1: 		code = ILCode.Ldloc; operand = methodBody.Variables[1]; break;
					case ILCode.__Ldloc_2: 		code = ILCode.Ldloc; operand = methodBody.Variables[2]; break;
					case ILCode.__Ldloc_3: 		code = ILCode.Ldloc; operand = methodBody.Variables[3]; break;
					case ILCode.__Stloc_0: 		code = ILCode.Stloc; operand = methodBody.Variables[0]; break;
					case ILCode.__Stloc_1: 		code = ILCode.Stloc; operand = methodBody.Variables[1]; break;
					case ILCode.__Stloc_2: 		code = ILCode.Stloc; operand = methodBody.Variables[2]; break;
					case ILCode.__Stloc_3: 		code = ILCode.Stloc; operand = methodBody.Variables[3]; break;
					case ILCode.__Ldarg_S: 		code = ILCode.Ldarg; break;
					case ILCode.__Ldarga_S: 		code = ILCode.Ldarga; break;
					case ILCode.__Starg_S: 		code = ILCode.Starg; break;
					case ILCode.__Ldloc_S: 		code = ILCode.Ldloc; break;
					case ILCode.__Ldloca_S: 		code = ILCode.Ldloca; break;
					case ILCode.__Stloc_S: 		code = ILCode.Stloc; break;
					case ILCode.__Ldc_I4_M1: 	code = ILCode.Ldc_I4; operand = -1; break;
					case ILCode.__Ldc_I4_0: 		code = ILCode.Ldc_I4; operand = 0; break;
					case ILCode.__Ldc_I4_1: 		code = ILCode.Ldc_I4; operand = 1; break;
					case ILCode.__Ldc_I4_2: 		code = ILCode.Ldc_I4; operand = 2; break;
					case ILCode.__Ldc_I4_3: 		code = ILCode.Ldc_I4; operand = 3; break;
					case ILCode.__Ldc_I4_4: 		code = ILCode.Ldc_I4; operand = 4; break;
					case ILCode.__Ldc_I4_5: 		code = ILCode.Ldc_I4; operand = 5; break;
					case ILCode.__Ldc_I4_6: 		code = ILCode.Ldc_I4; operand = 6; break;
					case ILCode.__Ldc_I4_7: 		code = ILCode.Ldc_I4; operand = 7; break;
					case ILCode.__Ldc_I4_8: 		code = ILCode.Ldc_I4; operand = 8; break;
					case ILCode.__Ldc_I4_S: 		code = ILCode.Ldc_I4; operand = (int) (sbyte) operand; break;
					case ILCode.__Br_S: 			code = ILCode.Br; break;
					case ILCode.__Brfalse_S: 	code = ILCode.__Brfalse; break;
					case ILCode.__Brtrue_S: 		code = ILCode.Brtrue; break;
					case ILCode.__Beq_S: 		code = ILCode.__Beq; break;
					case ILCode.__Bge_S: 		code = ILCode.__Bge; break;
					case ILCode.__Bgt_S: 		code = ILCode.__Bgt; break;
					case ILCode.__Ble_S: 		code = ILCode.__Ble; break;
					case ILCode.__Blt_S: 		code = ILCode.__Blt; break;
					case ILCode.__Bne_Un_S: 		code = ILCode.__Bne_Un; break;
					case ILCode.__Bge_Un_S: 		code = ILCode.__Bge_Un; break;
					case ILCode.__Bgt_Un_S: 		code = ILCode.__Bgt_Un; break;
					case ILCode.__Ble_Un_S: 		code = ILCode.__Ble_Un; break;
					case ILCode.__Blt_Un_S:		code = ILCode.__Blt_Un; break;
					case ILCode.__Leave_S:		code = ILCode.Leave; break;
			}
		}
Exemplo n.º 25
0
		static bool IsWithoutSideEffects(ILCode code)
		{
			return code == ILCode.Ldloc;
		}
Exemplo n.º 26
0
		public static void ExpandMacro(ref ILCode code, ref object operand, MethodBody methodBody)
		{
			switch (code) {
					case ILCode.__Ldarg_0:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(0); break;
					case ILCode.__Ldarg_1:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(1); break;
					case ILCode.__Ldarg_2:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(2); break;
					case ILCode.__Ldarg_3:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(3); break;
					case ILCode.__Ldloc_0:   code = ILCode.Ldloc; operand = methodBody.Variables[0]; break;
					case ILCode.__Ldloc_1:   code = ILCode.Ldloc; operand = methodBody.Variables[1]; break;
					case ILCode.__Ldloc_2:   code = ILCode.Ldloc; operand = methodBody.Variables[2]; break;
					case ILCode.__Ldloc_3:   code = ILCode.Ldloc; operand = methodBody.Variables[3]; break;
					case ILCode.__Stloc_0:   code = ILCode.Stloc; operand = methodBody.Variables[0]; break;
					case ILCode.__Stloc_1:   code = ILCode.Stloc; operand = methodBody.Variables[1]; break;
					case ILCode.__Stloc_2:   code = ILCode.Stloc; operand = methodBody.Variables[2]; break;
					case ILCode.__Stloc_3:   code = ILCode.Stloc; operand = methodBody.Variables[3]; break;
					case ILCode.__Ldarg_S:   code = ILCode.__Ldarg; break;
					case ILCode.__Ldarga_S:  code = ILCode.__Ldarga; break;
					case ILCode.__Starg_S:   code = ILCode.__Starg; break;
					case ILCode.__Ldloc_S:   code = ILCode.Ldloc; break;
					case ILCode.__Ldloca_S:  code = ILCode.Ldloca; break;
					case ILCode.__Stloc_S:   code = ILCode.Stloc; break;
					case ILCode.__Ldc_I4_M1: code = ILCode.Ldc_I4; operand = -1; break;
					case ILCode.__Ldc_I4_0:  code = ILCode.Ldc_I4; operand = 0; break;
					case ILCode.__Ldc_I4_1:  code = ILCode.Ldc_I4; operand = 1; break;
					case ILCode.__Ldc_I4_2:  code = ILCode.Ldc_I4; operand = 2; break;
					case ILCode.__Ldc_I4_3:  code = ILCode.Ldc_I4; operand = 3; break;
					case ILCode.__Ldc_I4_4:  code = ILCode.Ldc_I4; operand = 4; break;
					case ILCode.__Ldc_I4_5:  code = ILCode.Ldc_I4; operand = 5; break;
					case ILCode.__Ldc_I4_6:  code = ILCode.Ldc_I4; operand = 6; break;
					case ILCode.__Ldc_I4_7:  code = ILCode.Ldc_I4; operand = 7; break;
					case ILCode.__Ldc_I4_8:  code = ILCode.Ldc_I4; operand = 8; break;
					case ILCode.__Ldc_I4_S:  code = ILCode.Ldc_I4; operand = (int) (sbyte) operand; break;
					case ILCode.__Br_S:      code = ILCode.Br; break;
					case ILCode.__Brfalse_S: code = ILCode.__Brfalse; break;
					case ILCode.__Brtrue_S:  code = ILCode.Brtrue; break;
					case ILCode.__Beq_S:     code = ILCode.__Beq; break;
					case ILCode.__Bge_S:     code = ILCode.__Bge; break;
					case ILCode.__Bgt_S:     code = ILCode.__Bgt; break;
					case ILCode.__Ble_S:     code = ILCode.__Ble; break;
					case ILCode.__Blt_S:     code = ILCode.__Blt; break;
					case ILCode.__Bne_Un_S:  code = ILCode.__Bne_Un; break;
					case ILCode.__Bge_Un_S:  code = ILCode.__Bge_Un; break;
					case ILCode.__Bgt_Un_S:  code = ILCode.__Bgt_Un; break;
					case ILCode.__Ble_Un_S:  code = ILCode.__Ble_Un; break;
					case ILCode.__Blt_Un_S:  code = ILCode.__Blt_Un; break;
					case ILCode.__Leave_S:   code = ILCode.Leave; break;
					case ILCode.__Ldind_I:   code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.IntPtr; break;
					case ILCode.__Ldind_I1:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.SByte; break;
					case ILCode.__Ldind_I2:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Int16; break;
					case ILCode.__Ldind_I4:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Int32; break;
					case ILCode.__Ldind_I8:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Int64; break;
					case ILCode.__Ldind_U1:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Byte; break;
					case ILCode.__Ldind_U2:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.UInt16; break;
					case ILCode.__Ldind_U4:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.UInt32; break;
					case ILCode.__Ldind_R4:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Single; break;
					case ILCode.__Ldind_R8:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Double; break;
					case ILCode.__Stind_I:   code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.IntPtr; break;
					case ILCode.__Stind_I1:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Byte; break;
					case ILCode.__Stind_I2:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int16; break;
					case ILCode.__Stind_I4:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int32; break;
					case ILCode.__Stind_I8:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int64; break;
					case ILCode.__Stind_R4:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Single; break;
					case ILCode.__Stind_R8:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Double; break;
			}
		}
Exemplo n.º 27
0
 public OpString(ILCode aCode, int aPosition, int aNextPosition, string aValue, ExceptionHandlingClause aEhc)
     : base(aCode, aPosition, aNextPosition, aEhc)
 {
     Value = aValue;
 }
Exemplo n.º 28
0
        public static List <ILCode> ReadILCodes(string[] lines, List <string> locals = null, List <string> args = null)
        {
            var list = new List <ILCode>();

            //重置堆栈
            list.Add(new ILCode()
            {
                OpCode = "Reset",
                Line   = "Reset",
            });

            bool          switchStart = false;
            StringBuilder sline       = new StringBuilder();


            foreach (var xline in lines)
            {
                var line   = xline;
                var values = line.Trim().Split(' ');

                if (values.Length >= 2 && values[1] == "switch")
                {
                    switchStart = true;
                    sline       = new StringBuilder();
                }
                if (switchStart)
                {
                    sline.Append(line);
                    if (line.EndsWith(")"))
                    {
                        switchStart = false;
                        line        = sline.ToString();
                        values      = line.Trim().Split(' ');
                    }
                    else
                    {
                        continue;
                    }
                }



                if (values.Length > 4)
                {
                    for (int i = 5; i < values.Length; i++)
                    {
                        values[4] += " " + values[i];
                    }
                }
                {
                    //如果是字符串
                    int index  = line.IndexOf("\"");
                    int indexe = line.LastIndexOf("\"");
                    if (indexe != -1 && index != -1)
                    {
                        var str     = line.Substring(index + 1, indexe - index - 1);
                        var subline = line.Substring(0, index + 1) + "str" + line.Substring(indexe);
                        values = subline.Trim().Split(' ');
                        var indexx = new List <string>(values).IndexOf("\"str\"");
                        values[indexx] = str;
                    }
                }


                var illine = new ILCode();
                illine.Line = line;
                if (list.Count > 0 &&
                    (list.Last().OpCode == "try" || list.Last().OpCode == "catch" || list.Last().OpCode == "finally"))
                {
                    list.Last().Arg1 = line;
                }

                list.Add(illine);

                for (int i = 0; i < values.Length; i++)
                {
                    if (i == 0)
                    {
                        illine.Lable = values[0].Replace(":", "");
                    }
                    if (i == 1)
                    {
                        illine.OpCode = values[1];
                        var opcodeValue = illine.OpCode.Split('.');
                        illine.Op = opcodeValue[0];
                        if (opcodeValue.Length >= 2)
                        {
                            illine.OpArg0 = opcodeValue[1];
                        }
                        if (opcodeValue.Length >= 3)
                        {
                            illine.OpArg1 = opcodeValue[2];
                        }
                    }
                    if (i == 2)
                    {
                        illine.Arg0 = values[2];
                    }
                    if (i == 3)
                    {
                        illine.Arg1 = values[3];
                    }
                    if (i == 4)
                    {
                        illine.Arg2 = values[4];
                    }
                }
            }
            list = FixTryCatchFinally(list);
            //解析 生成
            list = MergeCodes(list, locals, args);
            return(list);
        }
Exemplo n.º 29
0
        public bool SimplifyTernaryOperator(List <ILNode> body, ILBasicBlock head, int pos)
        {
            Debug.Assert(body.Contains(head));

            ILExpression condExpr;
            ILLabel      trueLabel;
            ILLabel      falseLabel;
            ILVariable   trueLocVar = null;
            ILExpression trueExpr;
            ILLabel      trueFall;
            ILVariable   falseLocVar = null;
            ILExpression falseExpr;
            ILLabel      falseFall;
            object       unused;

            if (head.MatchLastAndBr(ILCode.Brtrue, out trueLabel, out condExpr, out falseLabel) &&
                labelGlobalRefCount[trueLabel] == 1 &&
                labelGlobalRefCount[falseLabel] == 1 &&
                ((labelToBasicBlock[trueLabel].MatchSingleAndBr(ILCode.Stloc, out trueLocVar, out trueExpr, out trueFall) &&
                  labelToBasicBlock[falseLabel].MatchSingleAndBr(ILCode.Stloc, out falseLocVar, out falseExpr, out falseFall) &&
                  trueLocVar == falseLocVar && trueFall == falseFall) ||
                 (labelToBasicBlock[trueLabel].MatchSingle(ILCode.Ret, out unused, out trueExpr) &&
                  labelToBasicBlock[falseLabel].MatchSingle(ILCode.Ret, out unused, out falseExpr))) &&
                body.Contains(labelToBasicBlock[trueLabel]) &&
                body.Contains(labelToBasicBlock[falseLabel])
                )
            {
                bool          isStloc          = trueLocVar != null;
                ILCode        opCode           = isStloc ? ILCode.Stloc : ILCode.Ret;
                TypeReference retType          = isStloc ? trueLocVar.Type : this.context.CurrentMethod.ReturnType;
                bool          retTypeIsBoolean = TypeAnalysis.IsBoolean(retType);
                int           leftBoolVal;
                int           rightBoolVal;
                ILExpression  newExpr;
                // a ? true:false  is equivalent to  a
                // a ? false:true  is equivalent to  !a
                // a ? true : b    is equivalent to  a || b
                // a ? b : true    is equivalent to  !a || b
                // a ? b : false   is equivalent to  a && b
                // a ? false : b   is equivalent to  !a && b
                if (retTypeIsBoolean &&
                    trueExpr.Match(ILCode.Ldc_I4, out leftBoolVal) &&
                    falseExpr.Match(ILCode.Ldc_I4, out rightBoolVal) &&
                    ((leftBoolVal != 0 && rightBoolVal == 0) || (leftBoolVal == 0 && rightBoolVal != 0))
                    )
                {
                    // It can be expressed as trivilal expression
                    if (leftBoolVal != 0)
                    {
                        newExpr = condExpr;
                    }
                    else
                    {
                        newExpr = new ILExpression(ILCode.LogicNot, null, condExpr);
                    }
                }
                else if (retTypeIsBoolean && trueExpr.Match(ILCode.Ldc_I4, out leftBoolVal))
                {
                    // It can be expressed as logical expression
                    if (leftBoolVal != 0)
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, condExpr, falseExpr);
                    }
                    else
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, new ILExpression(ILCode.LogicNot, null, condExpr), falseExpr);
                    }
                }
                else if (retTypeIsBoolean && falseExpr.Match(ILCode.Ldc_I4, out rightBoolVal))
                {
                    // It can be expressed as logical expression
                    if (rightBoolVal != 0)
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, new ILExpression(ILCode.LogicNot, null, condExpr), trueExpr);
                    }
                    else
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, condExpr, trueExpr);
                    }
                }
                else
                {
                    // Ternary operator tends to create long complicated return statements
                    if (opCode == ILCode.Ret)
                    {
                        return(false);
                    }

                    // Only simplify generated variables
                    if (opCode == ILCode.Stloc && !trueLocVar.IsGenerated)
                    {
                        return(false);
                    }

                    // Create ternary expression
                    newExpr = new ILExpression(ILCode.TernaryOp, null, condExpr, trueExpr, falseExpr);
                }

                head.Body.RemoveTail(ILCode.Brtrue, ILCode.Br);
                head.Body.Add(new ILExpression(opCode, trueLocVar, newExpr));
                if (isStloc)
                {
                    head.Body.Add(new ILExpression(ILCode.Br, trueFall));
                }

                // Remove the old basic blocks
                body.RemoveOrThrow(labelToBasicBlock[trueLabel]);
                body.RemoveOrThrow(labelToBasicBlock[falseLabel]);

                return(true);
            }
            return(false);
        }
Exemplo n.º 30
0
 ILExpression MakeLeftAssociativeShortCircuit(ILCode code, ILExpression left, ILExpression right)
 {
     // Assuming that the inputs are already left associative
     if (right.Match(code)) {
         // Find the leftmost logical expression
         ILExpression current = right;
         while(current.Arguments[0].Match(code))
             current = current.Arguments[0];
         current.Arguments[0].AddSelfAndChildrenRecursiveILRanges(current.ILRanges);
         current.Arguments[0] = new ILExpression(code, null, left, current.Arguments[0]) { InferredType = corLib.Boolean };
         return right;
     } else {
         return new ILExpression(code, null, left, right) { InferredType = corLib.Boolean };
     }
 }
		static bool CanBeRepresentedAsCompoundAssignment(ILCode code)
		{
			switch (code) {
				case ILCode.Add:
				case ILCode.Add_Ovf:
				case ILCode.Add_Ovf_Un:
				case ILCode.Sub:
				case ILCode.Sub_Ovf:
				case ILCode.Sub_Ovf_Un:
				case ILCode.Mul:
				case ILCode.Mul_Ovf:
				case ILCode.Mul_Ovf_Un:
				case ILCode.Div:
				case ILCode.Div_Un:
				case ILCode.Rem:
				case ILCode.Rem_Un:
				case ILCode.And:
				case ILCode.Or:
				case ILCode.Xor:
				case ILCode.Shl:
				case ILCode.Shr:
				case ILCode.Shr_Un:
					return true;
				default:
					return false;
			}
		}
Exemplo n.º 32
0
 public MethodPattern(ILCode code, string method, params Pattern[] arguments)
     : base(arguments)
 {
     this.code = code;
     this.method = method;
 }
Exemplo n.º 33
0
		bool isFlowControlCode(ILCode c)
		{
			switch (c) {
			case ILCode.__Brfalse_S:
			case ILCode.__Brtrue_S:
			case ILCode.__Beq_S:
			case ILCode.__Bge_S:
			case ILCode.__Bgt_S:
			case ILCode.__Ble_S:
			case ILCode.__Blt_S:
			case ILCode.__Bne_Un_S:
			case ILCode.__Bge_Un_S:
			case ILCode.__Bgt_Un_S:
			case ILCode.__Ble_Un_S:
			case ILCode.__Blt_Un_S:
			case ILCode.__Brfalse:
			case ILCode.Brtrue:
			case ILCode.__Beq:
			case ILCode.__Bge:
			case ILCode.__Bgt:
			case ILCode.__Ble:
			case ILCode.__Blt:
			case ILCode.__Bne_Un:
			case ILCode.__Bge_Un:
			case ILCode.__Bgt_Un:
			case ILCode.__Ble_Un:
			case ILCode.__Blt_Un:
				return true;
			default:
				break;
			}

			return false;
		}
Exemplo n.º 34
0
 public static string GetName(this ILCode code)
 {
     return(code.ToString().ToLowerInvariant().TrimStart('_').Replace('_', '.'));
 }
Exemplo n.º 35
0
 static bool IsStoreToArray(ILCode code)
 {
     switch (code) {
         case ILCode.Stelem_Any:
         case ILCode.Stelem_I:
         case ILCode.Stelem_I1:
         case ILCode.Stelem_I2:
         case ILCode.Stelem_I4:
         case ILCode.Stelem_I8:
         case ILCode.Stelem_R4:
         case ILCode.Stelem_R8:
         case ILCode.Stelem_Ref:
             return true;
         default:
             return false;
     }
 }
Exemplo n.º 36
0
        public static void ExpandMacro(ref ILCode code, ref object operand, MethodBody methodBody)
        {
            switch (code)
            {
            case ILCode.__Ldarg_0:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(0); break;

            case ILCode.__Ldarg_1:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(1); break;

            case ILCode.__Ldarg_2:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(2); break;

            case ILCode.__Ldarg_3:   code = ILCode.__Ldarg; operand = methodBody.GetParameter(3); break;

            case ILCode.__Ldloc_0:   code = ILCode.Ldloc; operand = methodBody.Variables[0]; break;

            case ILCode.__Ldloc_1:   code = ILCode.Ldloc; operand = methodBody.Variables[1]; break;

            case ILCode.__Ldloc_2:   code = ILCode.Ldloc; operand = methodBody.Variables[2]; break;

            case ILCode.__Ldloc_3:   code = ILCode.Ldloc; operand = methodBody.Variables[3]; break;

            case ILCode.__Stloc_0:   code = ILCode.Stloc; operand = methodBody.Variables[0]; break;

            case ILCode.__Stloc_1:   code = ILCode.Stloc; operand = methodBody.Variables[1]; break;

            case ILCode.__Stloc_2:   code = ILCode.Stloc; operand = methodBody.Variables[2]; break;

            case ILCode.__Stloc_3:   code = ILCode.Stloc; operand = methodBody.Variables[3]; break;

            case ILCode.__Ldarg_S:   code = ILCode.__Ldarg; break;

            case ILCode.__Ldarga_S:  code = ILCode.__Ldarga; break;

            case ILCode.__Starg_S:   code = ILCode.__Starg; break;

            case ILCode.__Ldloc_S:   code = ILCode.Ldloc; break;

            case ILCode.__Ldloca_S:  code = ILCode.Ldloca; break;

            case ILCode.__Stloc_S:   code = ILCode.Stloc; break;

            case ILCode.__Ldc_I4_M1: code = ILCode.Ldc_I4; operand = -1; break;

            case ILCode.__Ldc_I4_0:  code = ILCode.Ldc_I4; operand = 0; break;

            case ILCode.__Ldc_I4_1:  code = ILCode.Ldc_I4; operand = 1; break;

            case ILCode.__Ldc_I4_2:  code = ILCode.Ldc_I4; operand = 2; break;

            case ILCode.__Ldc_I4_3:  code = ILCode.Ldc_I4; operand = 3; break;

            case ILCode.__Ldc_I4_4:  code = ILCode.Ldc_I4; operand = 4; break;

            case ILCode.__Ldc_I4_5:  code = ILCode.Ldc_I4; operand = 5; break;

            case ILCode.__Ldc_I4_6:  code = ILCode.Ldc_I4; operand = 6; break;

            case ILCode.__Ldc_I4_7:  code = ILCode.Ldc_I4; operand = 7; break;

            case ILCode.__Ldc_I4_8:  code = ILCode.Ldc_I4; operand = 8; break;

            case ILCode.__Ldc_I4_S:  code = ILCode.Ldc_I4; operand = (int)(sbyte)operand; break;

            case ILCode.__Br_S:      code = ILCode.Br; break;

            case ILCode.__Brfalse_S: code = ILCode.__Brfalse; break;

            case ILCode.__Brtrue_S:  code = ILCode.Brtrue; break;

            case ILCode.__Beq_S:     code = ILCode.__Beq; break;

            case ILCode.__Bge_S:     code = ILCode.__Bge; break;

            case ILCode.__Bgt_S:     code = ILCode.__Bgt; break;

            case ILCode.__Ble_S:     code = ILCode.__Ble; break;

            case ILCode.__Blt_S:     code = ILCode.__Blt; break;

            case ILCode.__Bne_Un_S:  code = ILCode.__Bne_Un; break;

            case ILCode.__Bge_Un_S:  code = ILCode.__Bge_Un; break;

            case ILCode.__Bgt_Un_S:  code = ILCode.__Bgt_Un; break;

            case ILCode.__Ble_Un_S:  code = ILCode.__Ble_Un; break;

            case ILCode.__Blt_Un_S:  code = ILCode.__Blt_Un; break;

            case ILCode.__Leave_S:   code = ILCode.Leave; break;

            case ILCode.__Ldind_I:   code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.IntPtr; break;

            case ILCode.__Ldind_I1:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.SByte; break;

            case ILCode.__Ldind_I2:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Int16; break;

            case ILCode.__Ldind_I4:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Int32; break;

            case ILCode.__Ldind_I8:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Int64; break;

            case ILCode.__Ldind_U1:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Byte; break;

            case ILCode.__Ldind_U2:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.UInt16; break;

            case ILCode.__Ldind_U4:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.UInt32; break;

            case ILCode.__Ldind_R4:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Single; break;

            case ILCode.__Ldind_R8:  code = ILCode.Ldobj; operand = methodBody.Method.Module.TypeSystem.Double; break;

            case ILCode.__Stind_I:   code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.IntPtr; break;

            case ILCode.__Stind_I1:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Byte; break;

            case ILCode.__Stind_I2:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int16; break;

            case ILCode.__Stind_I4:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int32; break;

            case ILCode.__Stind_I8:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Int64; break;

            case ILCode.__Stind_R4:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Single; break;

            case ILCode.__Stind_R8:  code = ILCode.Stobj; operand = methodBody.Method.Module.TypeSystem.Double; break;
            }
        }
Exemplo n.º 37
0
        public bool SimplifyCustomShortCircuit(List <ILNode> body, ILBasicBlock head, int pos)
        {
            Debug.Assert(body.Contains(head));

            // --- looking for the following pattern ---
            // stloc(targetVar, leftVar)
            // brtrue(exitLabel, call(op_False, leftVar)
            // br(followingBlock)
            //
            // FollowingBlock:
            // stloc(targetVar, call(op_BitwiseAnd, leftVar, rightExpression))
            // br(exitLabel)
            // ---

            if (head.Body.Count < 3)
            {
                return(false);
            }

            // looking for:
            // stloc(targetVar, leftVar)
            ILVariable   targetVar;
            ILExpression targetVarInitExpr;

            if (!head.Body[head.Body.Count - 3].Match(ILCode.Stloc, out targetVar, out targetVarInitExpr))
            {
                return(false);
            }

            ILVariable leftVar;

            if (!targetVarInitExpr.Match(ILCode.Ldloc, out leftVar))
            {
                return(false);
            }

            // looking for:
            // brtrue(exitLabel, call(op_False, leftVar)
            // br(followingBlock)
            ILExpression callExpr;
            ILLabel      exitLabel;
            ILLabel      followingBlock;

            if (!head.MatchLastAndBr(ILCode.Brtrue, out exitLabel, out callExpr, out followingBlock))
            {
                return(false);
            }

            if (labelGlobalRefCount[followingBlock] > 1)
            {
                return(false);
            }

            IMethod      opFalse;
            ILExpression opFalseArg;

            if (!callExpr.Match(ILCode.Call, out opFalse, out opFalseArg))
            {
                return(false);
            }

            // ignore operators other than op_False and op_True
            if (opFalse.Name != "op_False" && opFalse.Name != "op_True")
            {
                return(false);
            }

            if (!opFalseArg.MatchLdloc(leftVar))
            {
                return(false);
            }

            ILBasicBlock followingBasicBlock = labelToBasicBlock[followingBlock];

            // FollowingBlock:
            // stloc(targetVar, call(op_BitwiseAnd, leftVar, rightExpression))
            // br(exitLabel)
            ILVariable   _targetVar;
            ILExpression opBitwiseCallExpr;
            ILLabel      _exitLabel;

            if (!followingBasicBlock.MatchSingleAndBr(ILCode.Stloc, out _targetVar, out opBitwiseCallExpr, out _exitLabel))
            {
                return(false);
            }

            if (_targetVar != targetVar || exitLabel != _exitLabel)
            {
                return(false);
            }

            IMethod      opBitwise;
            ILExpression leftVarExpression;
            ILExpression rightExpression;

            if (!opBitwiseCallExpr.Match(ILCode.Call, out opBitwise, out leftVarExpression, out rightExpression))
            {
                return(false);
            }

            if (!leftVarExpression.MatchLdloc(leftVar))
            {
                return(false);
            }

            // ignore operators other than op_BitwiseAnd and op_BitwiseOr
            if (opBitwise.Name != "op_BitwiseAnd" && opBitwise.Name != "op_BitwiseOr")
            {
                return(false);
            }

            // insert:
            // stloc(targetVar, LogicAnd(C::op_BitwiseAnd, leftVar, rightExpression)
            // br(exitLabel)
            ILCode op = opBitwise.Name == "op_BitwiseAnd" ? ILCode.LogicAnd : ILCode.LogicOr;

            if (op == ILCode.LogicAnd && opFalse.Name != "op_False")
            {
                return(false);
            }

            if (op == ILCode.LogicOr && opFalse.Name != "op_True")
            {
                return(false);
            }

            ILExpression shortCircuitExpr = MakeLeftAssociativeShortCircuit(op, opFalseArg, rightExpression);

            shortCircuitExpr.Operand = opBitwise;

            var tail = head.Body.RemoveTail(ILCode.Stloc, ILCode.Brtrue, ILCode.Br);

            //TODO: Keep tail's ILRanges
            //TODO: Keep ILRanges of other things that are removed by this method
            head.Body.Add(new ILExpression(ILCode.Stloc, targetVar, shortCircuitExpr));
            head.Body.Add(new ILExpression(ILCode.Br, exitLabel));
            body.Remove(followingBasicBlock);

            return(true);
        }
Exemplo n.º 38
0
        List <ByteCode> StackAnalysis(MethodDefinition methodDef)
        {
            Dictionary <Instruction, ByteCode> instrToByteCode = new Dictionary <Instruction, ByteCode>();

            // Create temporary structure for the stack analysis
            List <ByteCode>    body     = new List <ByteCode>(methodDef.Body.Instructions.Count);
            List <Instruction> prefixes = null;

            foreach (Instruction inst in methodDef.Body.Instructions)
            {
                if (inst.OpCode.OpCodeType == OpCodeType.Prefix)
                {
                    if (prefixes == null)
                    {
                        prefixes = new List <Instruction>(1);
                    }
                    prefixes.Add(inst);
                    continue;
                }
                ILCode code    = (ILCode)inst.OpCode.Code;
                object operand = inst.Operand;
                ILCodeUtil.ExpandMacro(ref code, ref operand, methodDef.Body);
                ByteCode byteCode = new ByteCode()
                {
                    Offset    = inst.Offset,
                    EndOffset = inst.Next != null ? inst.Next.Offset : methodDef.Body.CodeSize,
                    Code      = code,
                    Operand   = operand,
                    PopCount  = inst.GetPopDelta(methodDef),
                    PushCount = inst.GetPushDelta()
                };
                if (prefixes != null)
                {
                    instrToByteCode[prefixes[0]] = byteCode;
                    byteCode.Offset   = prefixes[0].Offset;
                    byteCode.Prefixes = prefixes.ToArray();
                    prefixes          = null;
                }
                else
                {
                    instrToByteCode[inst] = byteCode;
                }
                body.Add(byteCode);
            }
            for (int i = 0; i < body.Count - 1; i++)
            {
                body[i].Next = body[i + 1];
            }

            Stack <ByteCode> agenda = new Stack <ByteCode>();

            int varCount = methodDef.Body.Variables.Count;

            var exceptionHandlerStarts = new HashSet <ByteCode>(methodDef.Body.ExceptionHandlers.Select(eh => instrToByteCode[eh.HandlerStart]));

            // Add known states
            if (methodDef.Body.HasExceptionHandlers)
            {
                foreach (ExceptionHandler ex in methodDef.Body.ExceptionHandlers)
                {
                    ByteCode handlerStart = instrToByteCode[ex.HandlerStart];
                    handlerStart.StackBefore     = new List <StackSlot>();
                    handlerStart.VariablesBefore = VariableSlot.MakeFullState(varCount);
                    if (ex.HandlerType == ExceptionHandlerType.Catch || ex.HandlerType == ExceptionHandlerType.Filter)
                    {
                        // Catch and Filter handlers start with the exeption on the stack
                        ByteCode ldexception = new ByteCode()
                        {
                            Code      = ILCode.Ldexception,
                            Operand   = ex.CatchType,
                            PopCount  = 0,
                            PushCount = 1
                        };
                        ldexceptions[ex] = ldexception;
                        handlerStart.StackBefore.Add(new StackSlot(ldexception));
                    }
                    agenda.Push(handlerStart);

                    if (ex.HandlerType == ExceptionHandlerType.Filter)
                    {
                        ByteCode filterStart = instrToByteCode[ex.FilterStart];
                        filterStart.StackBefore     = new List <StackSlot>();
                        filterStart.VariablesBefore = VariableSlot.MakeFullState(varCount);
                        ByteCode ldexception = new ByteCode()
                        {
                            Code      = ILCode.Ldexception,
                            Operand   = ex.CatchType,
                            PopCount  = 0,
                            PushCount = 1
                        };
                        // TODO: ldexceptions[ex] = ldexception;
                        filterStart.StackBefore.Add(new StackSlot(ldexception));
                        agenda.Push(filterStart);
                    }
                }
            }

            body[0].StackBefore     = new List <StackSlot>();
            body[0].VariablesBefore = VariableSlot.MakeEmptyState(varCount);
            agenda.Push(body[0]);

            // Process agenda
            while (agenda.Count > 0)
            {
                ByteCode byteCode = agenda.Pop();

                // Calculate new stack
                List <StackSlot> newStack = StackSlot.CloneStack(byteCode.StackBefore, byteCode.PopCount);
                for (int i = 0; i < byteCode.PushCount; i++)
                {
                    newStack.Add(new StackSlot(byteCode));
                }

                // Calculate new variable state
                VariableSlot[] newVariableState = VariableSlot.CloneVariableState(byteCode.VariablesBefore);
                if (byteCode.Code == ILCode.Stloc)
                {
                    int varIndex = ((VariableReference)byteCode.Operand).Index;
                    newVariableState[varIndex] = new VariableSlot(byteCode);
                }

                // After the leave, finally block might have touched the variables
                if (byteCode.Code == ILCode.Leave)
                {
                    newVariableState = VariableSlot.MakeFullState(varCount);
                }

                // Find all successors
                List <ByteCode> branchTargets = new List <ByteCode>();
                if (!byteCode.Code.IsUnconditionalControlFlow())
                {
                    if (exceptionHandlerStarts.Contains(byteCode.Next))
                    {
                        // Do not fall though down to exception handler
                        // It is invalid IL as per ECMA-335 §12.4.2.8.1, but some obfuscators produce it
                    }
                    else
                    {
                        branchTargets.Add(byteCode.Next);
                    }
                }
                if (byteCode.Operand is Instruction[])
                {
                    foreach (Instruction inst in (Instruction[])byteCode.Operand)
                    {
                        ByteCode target = instrToByteCode[inst];
                        branchTargets.Add(target);
                        // The target of a branch must have label
                        if (target.Label == null)
                        {
                            target.Label = new ILLabel()
                            {
                                Name = target.Name
                            };
                        }
                    }
                }
                else if (byteCode.Operand is Instruction)
                {
                    ByteCode target = instrToByteCode[(Instruction)byteCode.Operand];
                    branchTargets.Add(target);
                    // The target of a branch must have label
                    if (target.Label == null)
                    {
                        target.Label = new ILLabel()
                        {
                            Name = target.Name
                        };
                    }
                }

                // Apply the state to successors
                foreach (ByteCode branchTarget in branchTargets)
                {
                    if (branchTarget.StackBefore == null && branchTarget.VariablesBefore == null)
                    {
                        if (branchTargets.Count == 1)
                        {
                            branchTarget.StackBefore     = newStack;
                            branchTarget.VariablesBefore = newVariableState;
                        }
                        else
                        {
                            // Do not share data for several bytecodes
                            branchTarget.StackBefore     = StackSlot.CloneStack(newStack, 0);
                            branchTarget.VariablesBefore = VariableSlot.CloneVariableState(newVariableState);
                        }
                        agenda.Push(branchTarget);
                    }
                    else
                    {
                        if (branchTarget.StackBefore.Count != newStack.Count)
                        {
                            throw new Exception("Inconsistent stack size at " + byteCode.Name);
                        }

                        // Be careful not to change our new data - it might be reused for several branch targets.
                        // In general, be careful that two bytecodes never share data structures.

                        bool modified = false;

                        // Merge stacks - modify the target
                        for (int i = 0; i < newStack.Count; i++)
                        {
                            ByteCode[] oldPushedBy = branchTarget.StackBefore[i].PushedBy;
                            ByteCode[] newPushedBy = oldPushedBy.Union(newStack[i].PushedBy);
                            if (newPushedBy.Length > oldPushedBy.Length)
                            {
                                branchTarget.StackBefore[i] = new StackSlot(newPushedBy, null);
                                modified = true;
                            }
                        }

                        // Merge variables - modify the target
                        for (int i = 0; i < newVariableState.Length; i++)
                        {
                            VariableSlot oldSlot = branchTarget.VariablesBefore[i];
                            VariableSlot newSlot = newVariableState[i];
                            // All can not be unioned further
                            if (!oldSlot.StoredByAll)
                            {
                                if (newSlot.StoredByAll)
                                {
                                    branchTarget.VariablesBefore[i] = newSlot;
                                    modified = true;
                                }
                                else
                                {
                                    ByteCode[] oldStoredBy = oldSlot.StoredBy;
                                    ByteCode[] newStoredBy = oldStoredBy.Union(newSlot.StoredBy);
                                    if (newStoredBy.Length > oldStoredBy.Length)
                                    {
                                        branchTarget.VariablesBefore[i] = new VariableSlot(newStoredBy, false);
                                        modified = true;
                                    }
                                }
                            }
                        }

                        if (modified)
                        {
                            agenda.Push(branchTarget);
                        }
                    }
                }
            }

            // Occasionally the compilers or obfuscators generate unreachable code (which migt be intentonally invalid)
            // I belive it is safe to just remove it
            body.RemoveAll(b => b.StackBefore == null);

            // Genertate temporary variables to replace stack
            foreach (ByteCode byteCode in body)
            {
                int argIdx   = 0;
                int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count;
                for (int i = byteCode.StackBefore.Count - popCount; i < byteCode.StackBefore.Count; i++)
                {
                    ILVariable tmpVar = new ILVariable()
                    {
                        Name = string.Format("arg_{0:X2}_{1}", byteCode.Offset, argIdx), IsGenerated = true
                    };
                    byteCode.StackBefore[i] = new StackSlot(byteCode.StackBefore[i].PushedBy, tmpVar);
                    foreach (ByteCode pushedBy in byteCode.StackBefore[i].PushedBy)
                    {
                        if (pushedBy.StoreTo == null)
                        {
                            pushedBy.StoreTo = new List <ILVariable>(1);
                        }
                        pushedBy.StoreTo.Add(tmpVar);
                    }
                    argIdx++;
                }
            }

            // Try to use single temporary variable insted of several if possilbe (especially useful for dup)
            // This has to be done after all temporary variables are assigned so we know about all loads
            foreach (ByteCode byteCode in body)
            {
                if (byteCode.StoreTo != null && byteCode.StoreTo.Count > 1)
                {
                    var locVars = byteCode.StoreTo;
                    // For each of the variables, find the location where it is loaded - there should be preciesly one
                    var loadedBy = locVars.Select(locVar => body.SelectMany(bc => bc.StackBefore).Single(s => s.LoadFrom == locVar)).ToList();
                    // We now know that all the variables have a single load,
                    // Let's make sure that they have also a single store - us
                    if (loadedBy.All(slot => slot.PushedBy.Length == 1 && slot.PushedBy[0] == byteCode))
                    {
                        // Great - we can reduce everything into single variable
                        ILVariable tmpVar = new ILVariable()
                        {
                            Name = string.Format("expr_{0:X2}", byteCode.Offset), IsGenerated = true
                        };
                        byteCode.StoreTo = new List <ILVariable>()
                        {
                            tmpVar
                        };
                        foreach (ByteCode bc in body)
                        {
                            for (int i = 0; i < bc.StackBefore.Count; i++)
                            {
                                // Is it one of the variable to be merged?
                                if (locVars.Contains(bc.StackBefore[i].LoadFrom))
                                {
                                    // Replace with the new temp variable
                                    bc.StackBefore[i] = new StackSlot(bc.StackBefore[i].PushedBy, tmpVar);
                                }
                            }
                        }
                    }
                }
            }

            // Split and convert the normal local variables
            ConvertLocalVariables(body);

            // Convert branch targets to labels
            foreach (ByteCode byteCode in body)
            {
                if (byteCode.Operand is Instruction[])
                {
                    List <ILLabel> newOperand = new List <ILLabel>();
                    foreach (Instruction target in (Instruction[])byteCode.Operand)
                    {
                        newOperand.Add(instrToByteCode[target].Label);
                    }
                    byteCode.Operand = newOperand.ToArray();
                }
                else if (byteCode.Operand is Instruction)
                {
                    byteCode.Operand = instrToByteCode[(Instruction)byteCode.Operand].Label;
                }
            }

            // Convert parameters to ILVariables
            ConvertParameters(body);

            return(body);
        }
Exemplo n.º 39
0
        public bool SimplifyTernaryOperator(List <ILNode> body, ILBasicBlock head, int pos)
        {
            Debug.Assert(body.Contains(head));

            ILExpression condExpr;
            ILLabel      trueLabel;
            ILLabel      falseLabel;
            ILVariable   trueLocVar = null;
            ILExpression trueExpr;
            ILLabel      trueFall;
            ILVariable   falseLocVar = null;
            ILExpression falseExpr;
            ILLabel      falseFall;
            object       unused;

            if (head.MatchLastAndBr(ILCode.Brtrue, out trueLabel, out condExpr, out falseLabel) &&
                labelGlobalRefCount[trueLabel] == 1 &&
                labelGlobalRefCount[falseLabel] == 1 &&
                ((labelToBasicBlock[trueLabel].MatchSingleAndBr(ILCode.Stloc, out trueLocVar, out trueExpr, out trueFall) &&
                  labelToBasicBlock[falseLabel].MatchSingleAndBr(ILCode.Stloc, out falseLocVar, out falseExpr, out falseFall) &&
                  trueLocVar == falseLocVar && trueFall == falseFall) ||
                 (labelToBasicBlock[trueLabel].MatchSingle(ILCode.Ret, out unused, out trueExpr) &&
                  labelToBasicBlock[falseLabel].MatchSingle(ILCode.Ret, out unused, out falseExpr))) &&
                body.Contains(labelToBasicBlock[trueLabel]) &&
                body.Contains(labelToBasicBlock[falseLabel])
                )
            {
                bool         isStloc          = trueLocVar != null;
                ILCode       opCode           = isStloc ? ILCode.Stloc : ILCode.Ret;
                TypeSig      retType          = isStloc ? trueLocVar.Type : this.context.CurrentMethod.ReturnType;
                bool         retTypeIsBoolean = retType.GetElementType() == ElementType.Boolean;
                int          leftBoolVal;
                int          rightBoolVal;
                ILExpression newExpr;
                // a ? true:false  is equivalent to  a
                // a ? false:true  is equivalent to  !a
                // a ? true : b    is equivalent to  a || b
                // a ? b : true    is equivalent to  !a || b
                // a ? b : false   is equivalent to  a && b
                // a ? false : b   is equivalent to  !a && b
                if (retTypeIsBoolean &&
                    trueExpr.Match(ILCode.Ldc_I4, out leftBoolVal) &&
                    falseExpr.Match(ILCode.Ldc_I4, out rightBoolVal) &&
                    ((leftBoolVal != 0 && rightBoolVal == 0) || (leftBoolVal == 0 && rightBoolVal != 0))
                    )
                {
                    // It can be expressed as trivilal expression
                    if (leftBoolVal != 0)
                    {
                        newExpr = condExpr;
                    }
                    else
                    {
                        newExpr = new ILExpression(ILCode.LogicNot, null, condExpr)
                        {
                            InferredType = corLib.Boolean
                        };
                    }
                }
                else if ((retTypeIsBoolean || falseExpr.InferredType.GetElementType() == ElementType.Boolean) && trueExpr.Match(ILCode.Ldc_I4, out leftBoolVal) && (leftBoolVal == 0 || leftBoolVal == 1))
                {
                    // It can be expressed as logical expression
                    if (leftBoolVal != 0)
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, condExpr, falseExpr);
                    }
                    else
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, new ILExpression(ILCode.LogicNot, null, condExpr), falseExpr);
                    }
                }
                else if ((retTypeIsBoolean || trueExpr.InferredType.GetElementType() == ElementType.Boolean) && falseExpr.Match(ILCode.Ldc_I4, out rightBoolVal) && (rightBoolVal == 0 || rightBoolVal == 1))
                {
                    // It can be expressed as logical expression
                    if (rightBoolVal != 0)
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicOr, new ILExpression(ILCode.LogicNot, null, condExpr), trueExpr);
                    }
                    else
                    {
                        newExpr = MakeLeftAssociativeShortCircuit(ILCode.LogicAnd, condExpr, trueExpr);
                    }
                }
                else
                {
                    // Ternary operator tends to create long complicated return statements
                    if (opCode == ILCode.Ret)
                    {
                        return(false);
                    }

                    // Only simplify generated variables
                    if (opCode == ILCode.Stloc && !trueLocVar.GeneratedByDecompiler)
                    {
                        return(false);
                    }

                    // Create ternary expression
                    newExpr = new ILExpression(ILCode.TernaryOp, null, condExpr, trueExpr, falseExpr);
                }

                var tail         = head.Body.RemoveTail(ILCode.Brtrue, ILCode.Br);
                var listNodes    = new List <ILNode>();
                var newExprNodes = newExpr.GetSelfAndChildrenRecursive <ILNode>(listNodes).ToArray();
                foreach (var node in labelToBasicBlock[trueLabel].GetSelfAndChildrenRecursive <ILNode>(listNodes).Except(newExprNodes))
                {
                    newExpr.ILRanges.AddRange(node.AllILRanges);
                }
                foreach (var node in labelToBasicBlock[falseLabel].GetSelfAndChildrenRecursive <ILNode>(listNodes).Except(newExprNodes))
                {
                    newExpr.ILRanges.AddRange(node.AllILRanges);
                }
                newExpr.ILRanges.AddRange(tail[0].ILRanges);
                tail[1].AddSelfAndChildrenRecursiveILRanges(newExpr.ILRanges);

                head.Body.Add(new ILExpression(opCode, trueLocVar, newExpr));
                if (isStloc)
                {
                    head.Body.Add(new ILExpression(ILCode.Br, trueFall));
                }

                // Remove the old basic blocks
                body.RemoveOrThrow(labelToBasicBlock[trueLabel]);
                body.RemoveOrThrow(labelToBasicBlock[falseLabel]);

                return(true);
            }
            return(false);
        }
Exemplo n.º 40
0
 public ILExpressionPrefix(ILCode code, object operand = null)
 {
     this.Code    = code;
     this.Operand = operand;
 }
Exemplo n.º 41
0
 public ILPattern(ILCode code, params Pattern[] arguments)
     : base(arguments)
 {
     this.code = code;
 }
Exemplo n.º 42
0
 public static void ExpandMacro(ref ILCode code, ref object operand, MethodDef method)
 {
     var methodBody = method.Body;
     switch (code) {
             case ILCode.Ldarg_0:   code = ILCode.Ldarg; operand = method.Parameters[0]; break;
             case ILCode.Ldarg_1:   code = ILCode.Ldarg; operand = method.Parameters[1]; break;
             case ILCode.Ldarg_2:   code = ILCode.Ldarg; operand = method.Parameters[2]; break;
             case ILCode.Ldarg_3:   code = ILCode.Ldarg; operand = method.Parameters[3]; break;
             case ILCode.Ldloc_0:   code = ILCode.Ldloc; operand = methodBody.Variables[0]; break;
             case ILCode.Ldloc_1:   code = ILCode.Ldloc; operand = methodBody.Variables[1]; break;
             case ILCode.Ldloc_2:   code = ILCode.Ldloc; operand = methodBody.Variables[2]; break;
             case ILCode.Ldloc_3:   code = ILCode.Ldloc; operand = methodBody.Variables[3]; break;
             case ILCode.Stloc_0:   code = ILCode.Stloc; operand = methodBody.Variables[0]; break;
             case ILCode.Stloc_1:   code = ILCode.Stloc; operand = methodBody.Variables[1]; break;
             case ILCode.Stloc_2:   code = ILCode.Stloc; operand = methodBody.Variables[2]; break;
             case ILCode.Stloc_3:   code = ILCode.Stloc; operand = methodBody.Variables[3]; break;
             case ILCode.Ldarg_S:   code = ILCode.Ldarg; break;
             case ILCode.Ldarga_S:  code = ILCode.Ldarga; break;
             case ILCode.Starg_S:   code = ILCode.Starg; break;
             case ILCode.Ldloc_S:   code = ILCode.Ldloc; break;
             case ILCode.Ldloca_S:  code = ILCode.Ldloca; break;
             case ILCode.Stloc_S:   code = ILCode.Stloc; break;
             case ILCode.Ldc_I4_M1: code = ILCode.Ldc_I4; operand = -1; break;
             case ILCode.Ldc_I4_0:  code = ILCode.Ldc_I4; operand = 0; break;
             case ILCode.Ldc_I4_1:  code = ILCode.Ldc_I4; operand = 1; break;
             case ILCode.Ldc_I4_2:  code = ILCode.Ldc_I4; operand = 2; break;
             case ILCode.Ldc_I4_3:  code = ILCode.Ldc_I4; operand = 3; break;
             case ILCode.Ldc_I4_4:  code = ILCode.Ldc_I4; operand = 4; break;
             case ILCode.Ldc_I4_5:  code = ILCode.Ldc_I4; operand = 5; break;
             case ILCode.Ldc_I4_6:  code = ILCode.Ldc_I4; operand = 6; break;
             case ILCode.Ldc_I4_7:  code = ILCode.Ldc_I4; operand = 7; break;
             case ILCode.Ldc_I4_8:  code = ILCode.Ldc_I4; operand = 8; break;
             case ILCode.Ldc_I4_S:  code = ILCode.Ldc_I4; operand = (int) (sbyte) operand; break;
             case ILCode.Br_S:      code = ILCode.Br; break;
             case ILCode.Brfalse_S: code = ILCode.Brfalse; break;
             case ILCode.Brtrue_S:  code = ILCode.Brtrue; break;
             case ILCode.Beq_S:     code = ILCode.Beq; break;
             case ILCode.Bge_S:     code = ILCode.Bge; break;
             case ILCode.Bgt_S:     code = ILCode.Bgt; break;
             case ILCode.Ble_S:     code = ILCode.Ble; break;
             case ILCode.Blt_S:     code = ILCode.Blt; break;
             case ILCode.Bne_Un_S:  code = ILCode.Bne_Un; break;
             case ILCode.Bge_Un_S:  code = ILCode.Bge_Un; break;
             case ILCode.Bgt_Un_S:  code = ILCode.Bgt_Un; break;
             case ILCode.Ble_Un_S:  code = ILCode.Ble_Un; break;
             case ILCode.Blt_Un_S:  code = ILCode.Blt_Un; break;
             case ILCode.Leave_S:   code = ILCode.Leave; break;
             case ILCode.Ldind_I:   code = ILCode.Ldobj; operand = method.Module.CorLibTypes.IntPtr.TypeDefOrRef; break;
             case ILCode.Ldind_I1:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.SByte.TypeDefOrRef; break;
             case ILCode.Ldind_I2:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.Int16.TypeDefOrRef; break;
             case ILCode.Ldind_I4:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.Int32.TypeDefOrRef; break;
             case ILCode.Ldind_I8:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.Int64.TypeDefOrRef; break;
             case ILCode.Ldind_U1:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.Byte.TypeDefOrRef; break;
             case ILCode.Ldind_U2:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.UInt16.TypeDefOrRef; break;
             case ILCode.Ldind_U4:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.UInt32.TypeDefOrRef; break;
             case ILCode.Ldind_R4:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.Single.TypeDefOrRef; break;
             case ILCode.Ldind_R8:  code = ILCode.Ldobj; operand = method.Module.CorLibTypes.Double.TypeDefOrRef; break;
             case ILCode.Stind_I:   code = ILCode.Stobj; operand = method.Module.CorLibTypes.IntPtr.TypeDefOrRef; break;
             case ILCode.Stind_I1:  code = ILCode.Stobj; operand = method.Module.CorLibTypes.Byte.TypeDefOrRef; break;
             case ILCode.Stind_I2:  code = ILCode.Stobj; operand = method.Module.CorLibTypes.Int16.TypeDefOrRef; break;
             case ILCode.Stind_I4:  code = ILCode.Stobj; operand = method.Module.CorLibTypes.Int32.TypeDefOrRef; break;
             case ILCode.Stind_I8:  code = ILCode.Stobj; operand = method.Module.CorLibTypes.Int64.TypeDefOrRef; break;
             case ILCode.Stind_R4:  code = ILCode.Stobj; operand = method.Module.CorLibTypes.Single.TypeDefOrRef; break;
             case ILCode.Stind_R8:  code = ILCode.Stobj; operand = method.Module.CorLibTypes.Double.TypeDefOrRef; break;
     }
 }
Exemplo n.º 43
0
 public MethodPattern(ILCode code, string method, params Pattern[] arguments)
     : base(arguments)
 {
     this.code   = code;
     this.method = method;
 }
Exemplo n.º 44
0
 public ILInstructionPattern(ILCode opCode, object operand, params ILExpressionPattern[] arguments)
     : this(new ILOpCodePattern(opCode), new ILOperandPattern(operand), arguments)
 {
 }
Exemplo n.º 45
0
 public VariablePattern(ILCode code, bool b)
     : base(null)
 {
     this.code = code;
     this.b    = b;
 }