Exemple #1
0
        static void ImplementIParser_SupportsTrace(TypeBuilder typeBuilder, Type baseType)
        {
            var baseMethod = ILHelper.GetMethod(baseType, "get_Trace");

            var impMethod = typeBuilder.DefineMethod(
                "IParser.SupportsTrace",
                MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual,
                typeof(bool),
                Type.EmptyTypes);

            var gen = impMethod.GetILGenerator();

            gen.Emit(baseMethod == null ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
            gen.Emit(OpCodes.Ret);

            typeBuilder.DefineMethodOverride(impMethod, ILHelper.GetMethod(typeof(IParser), "get_SupportsTrace"));
        }
Exemple #2
0
        public static void GenerateCLRBindingByAnalysis()
        {
            //GenerateCLRBinding();

            //用新的分析热更dll调用引用来生成绑定代码
            ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain();
            using (FileStream fs = new FileStream(ConfigPath.AnalysisCodePath, FileMode.Open, FileAccess.Read))
            {
                domain.LoadAssembly(fs);
                //Crossbind Adapter is needed to generate the correct binding code
                ILHelper.InitILRuntime(domain);
                ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, ConfigPath.OutputPathBinding, ConfigPath.OutputPathBindingBase);

                AssetDatabase.Refresh();
            }
            UnityEngine.Debug.Log($"生成CLR绑定代码 SUCCESS");
        }
        public static void Start()
        {
#if ILRuntime
            ILHelper.InitILRuntime();
#endif

            Model.GameEntry.Hotfix.LateUpdateAction         = Update;
            Model.GameEntry.Hotfix.LateUpdateAction         = LateUpdate;
            Model.GameEntry.Hotfix.OnApplicationQuitAction  = OnApplicationQuit;
            Model.GameEntry.Hotfix.OnApplicationFocusAction = OnApplicationFocus;
            Model.GameEntry.Hotfix.OnApplicationPauseAction = OnApplicationPause;

            Model.GameEntry.Hotfix.OnMessage = OnMessage;

            Log.Debug("热更启动完成!");
            Game.Start();
        }
Exemple #4
0
        private static void CreateDeserializeMethod(TypeDefinition wrapper, ModuleDefinition module, IReadOnlyList <IExposedProperty> properties)
        {
            MethodDefinition m = wrapper.AddMethod <object>("Deserialize",
                                                            MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);

            ParameterDefinition paraId      = m.AddParameter <int>("id");
            ParameterDefinition paraReader  = m.AddParameter(module.GetTypeReference(typeof(MessagePackReader).MakeByRefType()), "reader");
            ParameterDefinition paraOptions = m.AddParameter <MessagePackSerializerOptions>("options");

            ILProcessor il = m.BeginEdit();

            il.EmitIfElse(properties, (property, index, next, body, fill) =>
            {
                // if (id == <id>)
                fill.Add(ILHelper.Ldarg(il, paraId));
                if (property.Id == 0)
                {
                    fill.Add(Instruction.Create(OpCodes.Brtrue, next));
                }
                else
                {
                    fill.Add(ILHelper.Int(property.Id));
                    fill.Add(Instruction.Create(OpCodes.Bne_Un, next));
                }
            }, (property, index, next, fill) =>
            {
                // return reader.Read()
                // return options.Resolver.GetFormatterWithVerify<Type>().Deserialize(ref reader, options)

                fill.AddRange(FormatterHelper.GetReadValue(property.FieldTypeComponentAware, module, il, paraReader, paraOptions));
                if (property.IsValueType)
                {
                    fill.Add(Instruction.Create(OpCodes.Box, property.FieldTypeComponentAware));
                }

                fill.Add(Instruction.Create(OpCodes.Ret));
            }, fill =>
            {
                // return null
                fill.Add(Instruction.Create(OpCodes.Ldnull));
                fill.Add(Instruction.Create(OpCodes.Ret));
            });

            m.EndEdit();
        }
Exemple #5
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var xVar       = ((OpVar)instr).Value;
            var xBody      = aMethod.GetMethodBody();
            var xField     = xBody.LocalVariables[xVar];
            var xSize      = xField.LocalType.SizeOf();
            var StackCount = xSize.Align() / 4;
            var EBPOffset  = ILHelper.MemoryOffset(xBody, xVar);

            var xAddress = StackCount * 4 + EBPOffset;

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.EAX, SourceReg = Registers.EBP
                    });
                Core.AssemblerCode.Add(new Sub {
                        DestinationReg = Registers.EAX, SourceRef = "0x" + xAddress.ToString("X")
                    });
                Core.AssemblerCode.Add(new Push {
                        DestinationReg = Registers.EAX
                    });
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
            Core.vStack.Push(4, xField.LocalType);
        }
Exemple #6
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var aParam        = ((OpVar)instr).Value;
            var xDisplacement = ILHelper.GetArgumentDisplacement(aMethod, aParam);

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.EBX, SourceRef = "0x" + xDisplacement.ToString("X")
                    });
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.EAX, SourceReg = Registers.EBP
                    });
                Core.AssemblerCode.Add(new Add {
                        DestinationReg = Registers.EAX, SourceReg = Registers.EBX
                    });
                Core.AssemblerCode.Add(new Push {
                        DestinationReg = Registers.EAX
                    });
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }

            Core.vStack.Push(4, typeof(uint));
        }
Exemple #7
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var xBranchs = ((OpSwitch)instr).Value;

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                Core.AssemblerCode.Add(new Pop {
                        DestinationReg = Registers.EAX
                    });
                for (int i = 0; i < xBranchs.Length; i++)
                {
                    Core.AssemblerCode.Add(new Cmp {
                            DestinationReg = Registers.EAX, SourceRef = "0x" + i.ToString("X")
                        });
                    string xLabel = ILHelper.GetLabel(aMethod, xBranchs[i]);
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JE, DestinationRef = xLabel
                        });
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }

            Core.vStack.Pop();
        }
Exemple #8
0
#pragma warning disable IDE0051 // Remove unused private members

        private void ModifyCopyrightTextDrawMethod(ILCursor c)
#pragma warning restore IDE0051 // Remove unused private members
        {
            if (!c.TryGotoNext(x => x.MatchLdstr("Copyright © 2017 Re-Logic")))
            {
                ILHelper.LogILError("ldstr", "Copyright © 2017 Re-Logic");
                return;
            }

            if (!c.TryGotoNext(x => x.MatchLdloc(179)))
            {
                ILHelper.LogILError("ldloc.s", "179");
                return;
            }

            for (int i = 0; i < 2; i++)
            {
                if (!c.TryGotoNext(x => x.MatchLdsfld(typeof(Main).GetField("spriteBatch", BindingFlags.Static | BindingFlags.Public))))
                {
                    ILHelper.LogILError("ldsfld", "Terraria.Main::spriteBatch");
                    return;
                }
            }

            c.Index++;

            c.RemoveRange(31);

            c.Emit(OpCodes.Ldloc_2);    // color
            c.Emit(OpCodes.Ldloc, 179); // text to draw
            c.EmitDelegate <Action <Color, string> >((color, text) =>
            {
                // Match the drawColor to what text would normally be drawn like
                // Thanks, Terraria
                Color drawColor = color;
                drawColor.R     = (byte)((255 + drawColor.R) / 2);
                drawColor.G     = (byte)((255 + drawColor.R) / 2);
                drawColor.B     = (byte)((255 + drawColor.R) / 2);
                drawColor.A     = (byte)(drawColor.A * 0.3f);

                Utils.DrawBorderString(Main.spriteBatch, text, new Vector2(Main.screenWidth - FontAssets.MouseText.Value.MeasureString(text).X - 10f, Main.screenHeight - 2f - FontAssets.MouseText.Value.MeasureString(text).Y), drawColor);
            });
        }
Exemple #9
0
        static void ImplementReduction(TypeBuilder typeBuilder, FieldInfo reduction, MethodInfo reductionMethod)
        {
            var paramInfos = reductionMethod.GetParameters();

            var builder = ILHelper.OverrideMethod(typeBuilder, reductionMethod);
            var gen     = builder.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, reduction);
            gen.Emit(OpCodes.Ldstr, reductionMethod.Name);
            gen.Emit(OpCodes.Ldc_I4, paramInfos.Length);
            gen.Emit(OpCodes.Newarr, typeof(object));

            for (var i = 0; i < paramInfos.Length; i++)
            {
                var paramType = paramInfos[i].ParameterType;

                gen.Emit(OpCodes.Dup);
                gen.Emit(OpCodes.Ldc_I4, i);
                gen.Emit(OpCodes.Ldarg, i + 1);

                if (paramType.IsValueType)
                {
                    gen.Emit(OpCodes.Box, paramType);
                }

                gen.Emit(OpCodes.Stelem, typeof(object));
            }

            gen.Emit(OpCodes.Callvirt, ILHelper.GetMethod(typeof(ReductionDelegate), "Invoke", typeof(string), typeof(object[])));

            if (reductionMethod.ReturnType.IsValueType)
            {
                gen.Emit(OpCodes.Unbox_Any, reductionMethod.ReturnType);
            }
            else if (reductionMethod.ReturnType != typeof(object))
            {
                gen.Emit(OpCodes.Castclass, reductionMethod.ReturnType);
            }

            gen.Emit(OpCodes.Ret);
        }
Exemple #10
0
        static void GenerateCLRBindingByAnalysis()
        {
            //用新的分析热更dll调用引用来生成绑定代码
            byte[] bytes = null;
            ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain();
            using (System.IO.FileStream fs = new System.IO.FileStream("Assets/DownLoad/Hotfix/Hotfix.dll.bytes", System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                bytes = new byte[fs.Length];
                fs.Read(bytes, 0, bytes.Length);
            }
            var dllStream = new System.IO.MemoryStream(bytes);

            domain.LoadAssembly(dllStream);
            //Crossbind Adapter is needed to generate the correct binding code
            ILHelper.InitILRuntime(domain);
            ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, "Assets/ZJY_Framework/ILRuntime/Generated");

            GenHotfixDelegate.GenOne();
            AssetDatabase.Refresh();
        }
Exemple #11
0
    public async static void GenerateCLRBindingByAnalysis()
    {
        GenerateCLRBinding();

        //用新的分析热更dll调用引用来生成绑定代码
        ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain();
        string dstPath = Utils.GetStreamAssetsPath();

        byte[] dllBytes = await Utils.LoadFileBytesAsync(dstPath + "/Hotfix.dll");

        using (System.IO.MemoryStream fs = new MemoryStream(dllBytes))
        {
            domain.LoadAssembly(fs);
            //Crossbind Adapter is needed to generate the correct binding code
            ILHelper.Initialize(domain);
            ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, ILBindingPath);
            AssetDatabase.Refresh();
        }
        UnityEngine.Debug.Log("ILBinding Code Generated");
    }
Exemple #12
0
        /// <summary>
        /// <para>Invoke the method </para>
        /// </summary>
        /// <param name="il"></param>
        /// <param name="methodInfo"></param>
        /// <param name="parameters"></param>
        private static void InvokeMethodProxy(ILHelper il, MethodInfo methodInfo, ParameterInfo[] parameters)
        {
            //il.BeginTry();

            for (int i = 0; i <= parameters.Length; i++)
            {
                il.LoadArgument(i);
            }

            il.InvokeMethod(methodInfo);

            if (methodInfo.ReturnType != typeof(void))
            {
                il
                .Box(methodInfo.ReturnType)
                .SetVar("Mtn.ReturnValue");
            }
            //il.BeginCatch();
            //il.ReThrow();
            //il.EndTry();
        }
Exemple #13
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var xEndException = aMethod.FullName() + ".Error";

            if (instr.Ehc != null && instr.Ehc.HandlerOffset > instr.Position)
            {
                xEndException = ILHelper.GetLabel(aMethod, instr.Ehc.HandlerOffset);
            }
            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                Core.AssemblerCode.Add(new Call(Helper.lblSetException, true));
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.ECX, SourceRef = "0x2"
                    });
                Core.AssemblerCode.Add(new Jmp {
                        DestinationRef = xEndException
                    });
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
            Core.vStack.Pop();
        }
Exemple #14
0
        static void CreateConstructor(TypeBuilder typeBuilder, FieldInfo reduction, Type baseType)
        {
            const MethodAttributes attributes =
                MethodAttributes.Public |
                MethodAttributes.HideBySig |
                MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName;

            var ctor = typeBuilder.DefineConstructor(
                attributes,
                CallingConventions.Standard,
                new Type[] { typeof(ReductionDelegate) });

            var gen = ctor.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Call, ILHelper.GetConstructor(baseType));
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Stfld, reduction);
            gen.Emit(OpCodes.Ret);
        }
Exemple #15
0
        /// <summary>
        ///     <para>Default call for atributtes by the Service Proxy before the methody body.</para>
        /// </summary>
        /// <param name="method">
        ///     <para>Method .</para>
        /// </param>
        /// <param name="il">
        ///     <para>Il from  assembly to override the method.</para>
        /// </param>
        /// <returns>
        ///     <para>true if can execute method</para>
        /// </returns>
        public override bool MtnBeforeExecution(MethodInfo method, ILHelper il)
        {
            const BindingFlags bindFlag =
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;

            il
            .CreateLocalVar("Mtn.IsAuthorized", typeof(bool), false)
            .LoadVar("Mtn.IsAuthorized")
            .InvokeMethod(typeof(Authorization), "IsAuthorized", bindFlag)
            .SetVar("Mtn.IsAuthorized")
            .LoadVar("Mtn.IsAuthorized")
            .GotoIfNotNullOrTrue("MtnAfterAuthorization");

            il
            .InvokeMethod(typeof(Authorization).GetProperty("UnauthorizedValue").GetGetMethod())
            .SetVar("Mtn.ReturnValue")
            .LoadVar("Mtn.ReturnValue")
            .GotoIfNotNullOrTrue("MtnAfterAll");

            il.MarkLabel("MtnAfterAuthorization");
            return(true);
        }
    static void GenerateCLRBindingByAnalysis()
    {
        List <Type> types = new List <Type>();

        types.Add(typeof(int));
        types.Add(typeof(float));
        types.Add(typeof(long));
        types.Add(typeof(object));
        types.Add(typeof(string));
        types.Add(typeof(Array));
        types.Add(typeof(Vector2));
        types.Add(typeof(Vector3));
        types.Add(typeof(Quaternion));
        types.Add(typeof(GameObject));
        types.Add(typeof(UnityEngine.Object));
        types.Add(typeof(Transform));
        types.Add(typeof(RectTransform));
        types.Add(typeof(Time));
        types.Add(typeof(Debug));

        //所有DLL内的类型的真实C#类型都是ILTypeInstance
        types.Add(typeof(List <ILRuntime.Runtime.Intepreter.ILTypeInstance>));

        ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(types, OutputPath);
        AssetDatabase.Refresh();

        //用新的分析热更dll调用引用来生成绑定代码
        ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain();

        using (FileStream fs = new FileStream(InputPath, FileMode.Open, FileAccess.Read))
        {
            domain.LoadAssembly(fs);
            //Crossbind Adapter is needed to generate the correct binding code
            ILHelper.InitILRuntime(domain);
            ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, OutputPath);
            AssetDatabase.Refresh();
        }
    }
Exemple #17
0
    async void LoadHotfix()
    {
        string root = Utils.GetStreamAssetsPath();

        byte [] dllBytes = await Utils.LoadFileBytesAsync(root + "/Hotfix.dll");

        byte [] pdbBytes = await Utils.LoadFileBytesAsync(root + "/Hotfix.pdb");

        if (dllBytes != null && pdbBytes != null)
        {
            Debug.Log("Load Hotfix.dll and Hotfix.pdb success");
            appdomain = new ILRuntime.Runtime.Enviorment.AppDomain();
            using (System.IO.MemoryStream fs = new MemoryStream(dllBytes))
            {
#if RELEASE
                appdomain.LoadAssembly(fs, null, null);
#else
                using (System.IO.MemoryStream p = new MemoryStream(pdbBytes))
                {
                    appdomain.LoadAssembly(fs, null, new Mono.Cecil.Pdb.PdbReaderProvider());
                }
#endif
            }
            ILHelper.Initialize(appdomain);
            ILRuntimeTest();
        }
        else
        {
            if (dllBytes == null)
            {
                Debug.Log("Load Hotfix.dll fail");
            }
            if (pdbBytes == null)
            {
                Debug.Log("Load Hotfix.pdb fail");
            }
        }
    }
Exemple #18
0
        static void ImplementIParser_Trace(TypeBuilder typeBuilder, Type baseType)
        {
            var baseMethod = ILHelper.GetMethod(baseType, "get_Trace");

            var impMethod = typeBuilder.DefineMethod(
                "IParser.Trace",
                MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.Virtual,
                typeof(string),
                Type.EmptyTypes);

            var gen = impMethod.GetILGenerator();

            if (baseMethod == null)
            {
                ILHelper.ThrowNotSupportedException(gen, "This parser does not support the Trace property.");
            }
            else
            {
                gen.Emit(OpCodes.Jmp, baseMethod);
            }

            typeBuilder.DefineMethodOverride(impMethod, ILHelper.GetMethod(typeof(IParser), "get_Trace"));
        }
    static void GenerateCLRBindingByAnalysis()
    {
        //用新的分析热更dll调用引用来生成绑定代码
        ILRuntime.Runtime.Enviorment.AppDomain domain = new ILRuntime.Runtime.Enviorment.AppDomain();
        using (FileStream fs = new FileStream("Assets/Res/Code/Hotfix.dll.bytes", FileMode.Open, FileAccess.Read))
        {
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, bytes.Length);
            var          data2 = RijndaelDecrypt("11111111111111111111111111111111", bytes);
            MemoryStream ms    = new MemoryStream(data2);

            domain.LoadAssembly(ms);
            //Crossbind Adapter is needed to generate the correct binding code
            ILHelper.InitILRuntime(domain);
            ILRuntime.Runtime.CLRBinding.BindingCodeGenerator.GenerateBindingCode(domain, "Assets/Model/ILBinding");
            //注释反射绑定
            string filePath = "Assets/Model/ILBinding/CLRBindings.cs";
            var    oldStr   = File.ReadAllText(filePath);
            var    newStr   = oldStr.Replace("System_Reflection_Assembly_Binding.Register(app);", "");
            File.WriteAllText(filePath, newStr);
            AssetDatabase.Refresh();
        }
    }
Exemple #20
0
        public static void CopyMethodBody(MethodInfo info, ILGenerator il, IEnumerable <Filter> filters)
        {
            var methodbody = info.GetMethodBody();

            if (il != null)
            {
                foreach (var item in methodbody.LocalVariables)
                {
                    il.DeclareLocal(item.LocalType, item.IsPinned);
                }
            }

            byte[] arr = methodbody.GetILAsByteArray();

            for (int i = 0; i < arr.Length;)
            {
                var code = ILHelper.GetOpCode(arr.AsSpan(i), ref i);
                int size = code.GetOperandSize(arr.AsSpan(i));

                bool applied = false;
                foreach (var filter in filters)
                {
                    applied = applied || filter.Apply(code, size, arr.AsSpan(i));
                    if (applied)
                    {
                        break;
                    }
                }

                if (!applied)
                {
                    throw new Exception("No filter is applied!");
                }

                i += size;
            }
        }
Exemple #21
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            //This is branch type IL
            var xOffset = ((OpBranch)instr).Value;
            //The target branch
            var xTrueLabel = ILHelper.GetLabel(aMethod, xOffset);

            //Just make the jump to given target branch
            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                //Just make a jump as simple as that =)
                Core.AssemblerCode.Add(new Jmp {
                        DestinationRef = xTrueLabel
                    });
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
        }
Exemple #22
0
 /// <summary>
 ///     <para>Default call for atributtes by the Service Proxy after the methody body.</para>
 /// </summary>
 /// <param name="method">
 ///     <para>Method .</para>
 /// </param>
 /// <param name="il">
 ///     <para>Il from  assembly to override the method.</para>
 /// </param>
 /// <returns>
 ///     <para>true if can execute method</para>
 /// </returns>
 public override bool MtnAfterExecution(MethodInfo method, ILHelper il)
 {
     return(true);
 }
Exemple #23
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            //Clt just check if value 2 > Value 1, if yes than push 0x1 else push 0x0
            var FirstStackItem  = Core.vStack.Pop();
            var SecondStackItem = Core.vStack.Pop();

            //Here Math.Max is not necessary because they should have same size to compare, but i'm not removing this
            var xSize         = Math.Max(FirstStackItem.Size, SecondStackItem.Size);
            var xCurrentLabel = ILHelper.GetLabel(aMethod, instr.Position);
            var xFinalLabel   = ILHelper.GetLabel(aMethod, instr.NextPosition);

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                switch (xSize)
                {
                case 1:
                case 2:
                case 4:
                {
                    if (FirstStackItem.IsFloat)                 //If one item is float then both will
                    {
                        Core.AssemblerCode.Add(new Movss {
                                    DestinationReg = Registers.XMM0, SourceReg = Registers.ESP, SourceIndirect = true
                                });                                                                                                                              //XMM0 => Value 2
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x4"
                                });
                        Core.AssemblerCode.Add(new Movss {
                                    DestinationReg = Registers.XMM1, SourceReg = Registers.ESP, SourceIndirect = true
                                });                                                                                                                              //XMM1 => Value 1
                        Core.AssemblerCode.Add(new Cmpss {
                                    DestinationReg = Registers.XMM0, SourceReg = Registers.XMM1, PseudoCode = ComparePseudoOpcodes.NotLessThanOrEqualTo
                                });                                                                                                                                                               //Value 1 < Value 2
                        Core.AssemblerCode.Add(new MovD {
                                    SourceReg = Registers.XMM0, DestinationReg = Registers.EBX
                                });
                        Core.AssemblerCode.Add(new And {
                                    DestinationReg = Registers.EBX, SourceRef = "0x1"
                                });
                        Core.AssemblerCode.Add(new Mov {
                                    SourceReg = Registers.EBX, DestinationReg = Registers.ESP, DestinationIndirect = true
                                });
                    }
                    else
                    {
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EAX
                                });                                                                         //Value 2
                        Core.AssemblerCode.Add(new Cmp {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true
                                });                                                                                                                          //Value 2 - Value 1
                        Core.AssemblerCode.Add(new Jmp {
                                    Condition = ConditionalJumpEnum.JA, DestinationRef = xCurrentLabel + ".true"
                                });
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x4"
                                });
                        //Not equal
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x0"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });

                        //equal
                        Core.AssemblerCode.Add(new Label(xCurrentLabel + ".true"));
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x4"
                                });
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x1"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });
                        Core.AssemblerCode.Add(new Label(xFinalLabel));
                    }
                }
                break;

                case 8:
                {
                    if (FirstStackItem.IsFloat)
                    {
                    }
                    else
                    {
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EAX
                                });                                                                         //Value 2
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EDX
                                });

                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EBX
                                });                                                                         //Value 1
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.ECX
                                });

                        Core.AssemblerCode.Add(new Sub {
                                    DestinationReg = Registers.EBX, SourceReg = Registers.EAX
                                });
                        Core.AssemblerCode.Add(new SubWithCarry {
                                    DestinationReg = Registers.ECX, SourceReg = Registers.EDX
                                });

                        Core.AssemblerCode.Add(new Jmp {
                                    Condition = ConditionalJumpEnum.JB, DestinationRef = xCurrentLabel + ".true"
                                });

                        //Not Less Than
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x0"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });

                        //Less Than
                        Core.AssemblerCode.Add(new Label(xCurrentLabel + ".true"));
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x1"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });

                        Core.AssemblerCode.Add(new Label(xFinalLabel));
                    }
                }
                break;
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
            Core.vStack.Push(4, typeof(bool));
        }
Exemple #24
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            //This is branch type IL
            var xOffset = ((OpBranch)instr).Value;
            //The brach label
            var xTrueLabel = ILHelper.GetLabel(aMethod, xOffset);
            //Just make a pop because we want only size of it
            var xSize = Core.vStack.Pop().Size;

            /*
             *  value is pushed onto the stack by a previous operation.
             *  value is popped from the stack;
             *  if value is false, branch to target.
             */

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                switch (xSize)
                {
                case 1:
                case 2:
                case 4:
                {
                    //***What we are going to do is***
                    //1) Pop the content into EAX
                    //2) Compare the content with 0x0 --> False
                    //3) If they are equal than jump to branch
                    Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                    Core.AssemblerCode.Add(new Cmp {
                                DestinationReg = Registers.EAX, SourceRef = "0x0"
                            });
                    Core.AssemblerCode.Add(new Jmp {
                                Condition = ConditionalJumpEnum.JE, DestinationRef = xTrueLabel
                            });
                }
                break;

                case 8:
                {
                    Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                    Core.AssemblerCode.Add(new Cmp {
                                DestinationReg = Registers.EAX, SourceRef = "0x0"
                            });

                    string xFalseLabel = xTrueLabel + ".false";
                    Core.AssemblerCode.Add(new Jmp {
                                Condition = ConditionalJumpEnum.JNE, DestinationRef = xFalseLabel
                            });
                    Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                    Core.AssemblerCode.Add(new Cmp {
                                DestinationReg = Registers.EAX, SourceRef = "0x0"
                            });
                    Core.AssemblerCode.Add(new Jmp {
                                Condition = ConditionalJumpEnum.JE, DestinationRef = xTrueLabel
                            });
                    Core.AssemblerCode.Add(new Label(xFalseLabel));
                }
                break;

                default:
                    //Size > 4 is never called don't know why
                    throw new Exception("@Brfalse: Unexpected size called := " + xSize);
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
        }
Exemple #25
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            //The Target method base which we have to call
            var xTarget = ((OpMethod)instr).Value;
            //Try to get if there is any method info of target method
            var xTargetInfo    = xTarget as MethodInfo;
            var xNormalAddress = xTarget.FullName();                             //Target method full name
            var xParams        = xTarget.GetParameters();
            var xNextAddress   = ILHelper.GetLabel(aMethod, instr.NextPosition); //Next address after call IL instruction

            /* Now to find error handling label
             * This is because if the called method throwed any exception than to handle that we need something.
             */
            var xEndException = aMethod.FullName() + ".Error";//Current method exception label

            //Check if there is any try catch field after this call instruction
            if (instr.Ehc != null && instr.Ehc.HandlerOffset > instr.Position)
            {
                //If yes take that label as excpetion handling label
                xEndException = ILHelper.GetLabel(aMethod, instr.Ehc.HandlerOffset);
            }

            //If method have any method info than check what is its return size
            //And also align it to stack pointer
            var xReturnSize = 0;

            if (xTargetInfo != null)
            {
                xReturnSize = xTargetInfo.ReturnType.SizeOf().Align();
            }

            /* Size to reserve can be viewed as the segment of stack that is require to call a function
             * where function can put it all its parameters/local variables
             * And finally the return size */
            #region Size2Reserve
            int SizeToReserve = xReturnSize;
            if (SizeToReserve > 0)
            {
                foreach (var xp in xTarget.GetParameters())
                {
                    SizeToReserve -= xp.ParameterType.SizeOf().Align();
                    Core.vStack.Pop();
                }
                if (!xTargetInfo.IsStatic)
                {
                    SizeToReserve -= (ILCompiler.CPUArchitecture == CompilerExt.CPUArch.x86 ? 4 : 8);
                    Core.vStack.Pop();
                }
            }
            #endregion

            /*
             *  Method arguments arg1 through argN are pushed onto the stack.
             *  Method arguments arg1 through argN are popped from the stack;
             *  the method call is performed with these arguments and control is transferred,
             *  to the method referred to by the method descriptor. When complete,
             *  a return value is generated by the callee method and sent to the caller.
             *  The return value is pushed onto the stack.
             */

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                //Make Space for extra requirements of function
                if (SizeToReserve > 0)
                {
                    Core.AssemblerCode.Add(new Sub {
                            DestinationReg = Registers.ESP, SourceRef = "0x" + SizeToReserve.ToString("X")
                        });
                }

                Core.AssemblerCode.Add(new Call(xNormalAddress));

                if (aMethod != null)
                {
                    //Check if ECX register has no error value that is 0x1
                    //If yes than jump to next instruction
                    Core.AssemblerCode.Add(new Test {
                            DestinationReg = Registers.ECX, SourceRef = "0x2"
                        });
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JE, DestinationRef = xNextAddress
                        });

                    Core.AssemblerCode.Add(new Add {
                            DestinationReg = Registers.ESP, SourceRef = "0x" + xReturnSize.ToString("x")
                        });
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JNE, DestinationRef = xEndException
                        });
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
            ///If there is not method info than why push anything to virtual stack
            if (xTargetInfo == null || xReturnSize == 0)
            {
                return;
            }

            Core.vStack.Push(xReturnSize, xTargetInfo.ReturnType);
        }
Exemple #26
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var xOperand      = ((OpMethod)instr);
            var xTargetMethod = xOperand.Value;
            var xTargetType   = xTargetMethod.DeclaringType;
            var xCurrentLabel = ILHelper.GetLabel(aMethod, xOperand.Position);

            var xEndException = aMethod.FullName() + ".Error";

            if (instr.Ehc != null && instr.Ehc.HandlerOffset > instr.Position)
            {
                xEndException = ILHelper.GetLabel(aMethod, instr.Ehc.HandlerOffset);
            }

            string xCctorAddress = null;

            if (aMethod != null)
            {
                var xCctor = (xTargetType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault();
                if (xCctor != null)
                {
                    xCctorAddress = xCctor.FullName();
                }
            }

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                if (xCctorAddress != null)
                {
                    Core.AssemblerCode.Add(new Call(xCctorAddress));
                    Core.AssemblerCode.Add(new Test {
                            DestinationReg = Registers.ECX, SourceRef = "0x2"
                        });
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JNE, DestinationRef = xEndException
                        });
                }

                if (xTargetType.IsValueType)
                {
                    int xStorageSize = xTargetType.SizeOf().Align();
                    int xArgSize     = 0;

                    var xParameterList = xTargetMethod.GetParameters();
                    foreach (var xParam in xParameterList)
                    {
                        xArgSize += xParam.ParameterType.SizeOf().Align();
                    }

                    int xShift = (int)(xArgSize - xStorageSize);
                    if (xShift < 0)
                    {
                        Core.AssemblerCode.Add(new Sub {
                                DestinationReg = Registers.ESP, SourceRef = "0x" + Math.Abs(xShift).ToString("X")
                            });
                    }
                    else if (xShift > 0)
                    {
                        Core.AssemblerCode.Add(new Add {
                                DestinationReg = Registers.ESP, SourceRef = "0x" + xShift.ToString("X")
                            });
                    }

                    //Create space for struc. pointer
                    Core.AssemblerCode.Add(new Push {
                            DestinationReg = Registers.ESP
                        });
                    Core.vStack.Push(4, typeof(IntPtr));

                    foreach (var xParam in xParameterList)
                    {
                        int xArgSizeForThis = xParam.ParameterType.SizeOf().Align();
                        Core.vStack.Push(xArgSizeForThis, xParam.ParameterType);
                        for (int i = 1; i <= xArgSizeForThis / 4; i++)
                        {
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.ESP, DestinationIndirect = true, DestinationDisplacement = (int)xStorageSize
                                });
                        }
                    }

                    new ILCall(this.Compiler).Execute(xOperand, aMethod);
                    Core.vStack.Push(xStorageSize, xTargetType);
                }
                else
                {
                    var xParams = xTargetMethod.GetParameters();
                    for (int i = 0; i < xParams.Length; i++)
                    {
                        Core.vStack.Pop();
                    }

                    bool xHasCalcSize = false;

                    if (xTargetType.ToString() == "System.String")
                    {
                        xHasCalcSize = true;

                        if (xParams.Length == 1 && xParams[0].ParameterType.ToString() == "System.Char[]")
                        {
                            Core.AssemblerCode.Add(new Mov {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true
                                });
                            Core.AssemblerCode.Add(new Mov {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.EAX, SourceIndirect = true, SourceDisplacement = 8
                                });
                            Core.AssemblerCode.Add(new ShiftLeft {
                                    DestinationReg = Registers.EAX, SourceRef = "0x1"
                                });
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.EAX
                                });
                        }
                        else if (xParams.Length == 1 && xParams[0].ParameterType.ToString() == "System.Char*")
                        {
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.ESP, DestinationIndirect = true
                                });
                            Core.AssemblerCode.Add(new Call("getLength_System_Char__", true));
                            Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EAX
                                });
                            Core.AssemblerCode.Add(new ShiftLeft {
                                    DestinationReg = Registers.EAX, SourceRef = "0x1"
                                });
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.EAX
                                });
                        }
                        else if (xParams.Length == 3 && xParams[0].ParameterType.ToString() == "System.Char[]" && xParams[1].ParameterType.ToString() == "System.Int32" && xParams[2].ParameterType.ToString() == "System.Int32")
                        {
                            Core.AssemblerCode.Add(new Mov {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true
                                });
                            Core.AssemblerCode.Add(new ShiftLeft {
                                    DestinationReg = Registers.EAX, SourceRef = "0x1"
                                });
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.EAX
                                });
                        }
                        else if (xParams.Length == 2 && xParams[0].ParameterType.ToString() == "System.Char" && xParams[1].ParameterType.ToString() == "System.Int32")
                        {
                            Core.AssemblerCode.Add(new Mov {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true
                                });
                            Core.AssemblerCode.Add(new ShiftLeft {
                                    DestinationReg = Registers.EAX, SourceRef = "0x1"
                                });
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.EAX
                                });
                        }
                        else
                        {
                            throw new NotImplementedException("In NewObj is a string ctor implementation missing!`" + xParams[0].ParameterType.ToString() + "`");
                        }
                    }

                    int xMemSize = ILHelper.StorageSize(xTargetType) + 12;
                    Core.AssemblerCode.Add(new Push {
                            DestinationRef = "0x" + xMemSize.ToString("X")
                        });
                    if (xHasCalcSize)
                    {
                        Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                        Core.AssemblerCode.Add(new Add {
                                DestinationReg = Registers.ESP, DestinationIndirect = true, SourceReg = Registers.EAX
                            });
                    }

                    //Call our Heap
                    Core.AssemblerCode.Add(new Call(Helper.lblHeap, true));
                    Core.AssemblerCode.Add(new Push {
                            DestinationReg = Registers.ESP, DestinationIndirect = true
                        });
                    Core.AssemblerCode.Add(new Push {
                            DestinationReg = Registers.ESP, DestinationIndirect = true
                        });

                    int xGCFieldCount = xTargetType.GetFields().Count(x => x.FieldType.IsValueType);

                    var xTypeID = ILHelper.GetTypeID(xTargetType);

                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EAX
                        });
                    Core.AssemblerCode.Add(new Mov {
                            DestinationReg = Registers.EAX, DestinationIndirect = true, SourceRef = "0x" + xTypeID.ToString("X")
                        });
                    Core.AssemblerCode.Add(new Mov {
                            DestinationReg = Registers.EAX, DestinationIndirect = true, DestinationDisplacement = 4, SourceRef = "0x1"
                        });
                    Core.AssemblerCode.Add(new Mov {
                            DestinationReg = Registers.EAX, DestinationIndirect = true, DestinationDisplacement = 8, SourceRef = "0x" + xMemSize.ToString("X")
                        });
                    uint xSize = (uint)(((from item in xParams
                                          let xQSize = item.ParameterType.SizeOf().Align()
                                                       select(int) xQSize).Take(xParams.Length).Sum()));

                    foreach (var xParam in xParams)
                    {
                        int xParamSize = xParam.ParameterType.SizeOf().Align();
                        for (int i = 0; i < xParamSize; i += 4)
                        {
                            Core.AssemblerCode.Add(new Push {
                                    DestinationReg = Registers.ESP, DestinationIndirect = true, DestinationDisplacement = (int)(xSize + 4)
                                });
                        }
                    }

                    Core.AssemblerCode.Add(new Call(xTargetMethod.FullName()));
                    if (aMethod != null)
                    {
                        Core.AssemblerCode.Add(new Test {
                                DestinationReg = Registers.ECX, SourceRef = "0x2"
                            });
                        string xNoErrorLabel = xCurrentLabel + ".NoError";
                        Core.AssemblerCode.Add(new Jmp {
                                Condition = ConditionalJumpEnum.JE, DestinationRef = xNoErrorLabel
                            });

                        PushAlignedParameterSize(xTargetMethod);
                        // an exception occurred, we need to cleanup the stack, and jump to the exit
                        Core.AssemblerCode.Add(new Add {
                                DestinationReg = Registers.ESP, SourceRef = "0x4"
                            });

                        int xESPOffset = 0;
                        foreach (var xParam in xParams)
                        {
                            xESPOffset += xParam.ParameterType.SizeOf().Align();
                        }
                        Core.AssemblerCode.Add(new Add {
                                DestinationReg = Registers.ESP, SourceRef = "0x" + xESPOffset.ToString("X")
                            });

                        Core.AssemblerCode.Add(new Jmp {
                                DestinationRef = aMethod.FullName() + ".Error"
                            });
                        Core.AssemblerCode.Add(new Label(xNoErrorLabel));
                    }
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EAX
                        });

                    PushAlignedParameterSize(xTargetMethod);

                    Core.AssemblerCode.Add(new Push {
                            DestinationReg = Registers.EAX
                        });
                    Core.vStack.Push(4, xTargetType);
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
        }
Exemple #27
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var FirstStackItem  = Core.vStack.Pop();
            var SecondStackItem = Core.vStack.Pop();

            var xSize         = Math.Max(FirstStackItem.Size, SecondStackItem.Size);
            var xCurrentLabel = ILHelper.GetLabel(aMethod, instr.Position);
            var xFinalLabel   = ILHelper.GetLabel(aMethod, instr.NextPosition);

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                /*Ceq checks if both values in stack are equal or not, if they are equal then they push 1 onto the stack else
                 * 0 is pushed to the stack
                 */
                switch (xSize)
                {
                case 1:
                case 2:
                case 4:
                {
                    if (FirstStackItem.IsFloat)                 //If one item is float then both will
                    {
                        Core.AssemblerCode.Add(new Movss {
                                    DestinationReg = Registers.XMM0, SourceReg = Registers.ESP, SourceIndirect = true
                                });
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x4"
                                });
                        Core.AssemblerCode.Add(new Movss {
                                    DestinationReg = Registers.XMM1, SourceReg = Registers.ESP, SourceIndirect = true
                                });
                        Core.AssemblerCode.Add(new Cmpss {
                                    DestinationReg = Registers.XMM0, SourceReg = Registers.XMM1, PseudoCode = ComparePseudoOpcodes.Equal
                                });
                        Core.AssemblerCode.Add(new MovD {
                                    SourceReg = Registers.XMM0, DestinationReg = Registers.EBX
                                });
                        Core.AssemblerCode.Add(new And {
                                    DestinationReg = Registers.EBX, SourceRef = "0x1"
                                });
                        Core.AssemblerCode.Add(new Mov {
                                    SourceReg = Registers.EBX, DestinationReg = Registers.ESP, DestinationIndirect = true
                                });
                    }
                    else
                    {
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EAX
                                });
                        Core.AssemblerCode.Add(new Cmp {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    Condition = ConditionalJumpEnum.JE, DestinationRef = xCurrentLabel + ".true"
                                });
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x4"
                                });
                        //Not equal
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x0"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });

                        //equal
                        Core.AssemblerCode.Add(new Label(xCurrentLabel + ".true"));
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x4"
                                });
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x1"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });
                        Core.AssemblerCode.Add(new Label(xFinalLabel));
                    }
                }
                break;

                case 8:
                {
                    if (FirstStackItem.IsFloat)
                    {
                    }
                    else
                    {
                        //Check Hight Part
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EAX
                                });
                        Core.AssemblerCode.Add(new Cmp {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true, SourceDisplacement = 0x4
                                });
                        Core.AssemblerCode.Add(new Pop {
                                    DestinationReg = Registers.EAX
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    Condition = ConditionalJumpEnum.JNE, DestinationRef = xCurrentLabel + ".false"
                                });

                        //Check Low part
                        Core.AssemblerCode.Add(new Xor {
                                    DestinationReg = Registers.EAX, SourceReg = Registers.ESP, SourceIndirect = true, SourceDisplacement = 0x4
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    Condition = ConditionalJumpEnum.JNZ, DestinationRef = xCurrentLabel + ".false"
                                });

                        //equal
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x8"
                                });
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x1"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });

                        //not equal
                        Core.AssemblerCode.Add(new Label(xCurrentLabel + ".false"));
                        Core.AssemblerCode.Add(new Assembler.x86.Add {
                                    DestinationReg = Registers.ESP, SourceRef = "0x8"
                                });
                        Core.AssemblerCode.Add(new Push {
                                    DestinationRef = "0x0"
                                });
                        Core.AssemblerCode.Add(new Jmp {
                                    DestinationRef = xFinalLabel
                                });
                        Core.AssemblerCode.Add(new Label(xFinalLabel));
                    }
                }
                break;
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
            Core.vStack.Push(4, typeof(bool));
        }
Exemple #28
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            //This is branch type IL
            var xOffset     = ((OpBranch)instr).Value;
            var xSize       = Core.vStack.Pop().Size;
            var xTrueLabel  = ILHelper.GetLabel(aMethod, xOffset);
            var xFalseLabel = ILHelper.GetLabel(aMethod, instr.Position) + "._bne_un_false";

            //Make a pop because exactly we are popping up two items
            Core.vStack.Pop();

            /*
             *  value1 is pushed onto the stack.
             *  value2 is pushed onto the stack.
             *  value2 and value1 are popped from the stack;
             *  if value1 is not equal to value2, the branch operation is performed. --> value1 ≠ value2
             */

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                if (xSize <= 4)
                {
                    //***What we are going to do is***
                    //1) Pop Value 2 into EAX
                    //2) Pop Value 1 into EBX
                    //3) Compare EAX and EBX, Jump to Branch when the result is not zero
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EAX
                        });                                                                    //Value 2
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EBX
                        });                                                                    //Value 1
                    Core.AssemblerCode.Add(new Cmp {
                            DestinationReg = Registers.EAX, SourceReg = Registers.EBX
                        });
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JNE, DestinationRef = xTrueLabel
                        });
                }
                else if (xSize <= 8)
                {
                    //***What we are going to do is***
                    //1) Pop Value 2 low into EAX and high into EBX
                    //2) Pop Value 1 low into ECX and high into EDX
                    //3) Compare low values and check if zero than continue else if not than jump to Not Equal
                    //4) Compare high values and check if zero than jump to Branch else continue

                    //Value 2 EBX:EAX
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EAX
                        });                                                                    //low
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EBX
                        });                                                                    //high

                    //Value 1 EDX:ECX
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.ECX
                        });                                                                    //low
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EDX
                        });                                                                    //high

                    Core.AssemblerCode.Add(new Cmp {
                            DestinationReg = Registers.EAX, SourceReg = Registers.ECX
                        });
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JNE, DestinationRef = xTrueLabel
                        });
                    Core.AssemblerCode.Add(new Cmp {
                            DestinationReg = Registers.EBX, SourceReg = Registers.EDX
                        });
                    Core.AssemblerCode.Add(new Jmp {
                            Condition = ConditionalJumpEnum.JNE, DestinationRef = xTrueLabel
                        });

                    Core.AssemblerCode.Add(new Label(xFalseLabel));
                }
                else
                {
                    //Not called usually
                    throw new Exception("@Bne_Un: Branch operation bne_un for size > 8 is not yet implemented");
                }
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }
        }
Exemple #29
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var xF             = ((OpField)instr).Value;
            var aDeclaringType = xF.DeclaringType;
            var xFieldId       = xF.FullName();

            FieldInfo xFieldInfo = null;

            //Now we have to calculate the offset of object, and also give us that field
            int  xOffset  = ILHelper.GetFieldOffset(aDeclaringType, xFieldId, out xFieldInfo);
            bool xNeedsGC = aDeclaringType.IsClass && !aDeclaringType.IsValueType;

            if (xNeedsGC)
            {
                xOffset += 12; //Extra offset =)
            }
            //As we are sure xFieldInfo should contain value as if not than it throws error in GetFieldOffset
            var xSize        = xFieldInfo.FieldType.SizeOf();
            var xRoundedSize = xSize.Align();

            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.EBX, SourceReg = Registers.ESP, SourceIndirect = true, SourceDisplacement = (int)xRoundedSize
                    });
                Core.AssemblerCode.Add(new Add {
                        DestinationReg = Registers.EBX, SourceRef = "0x" + xOffset.ToString("X")
                    });

                for (int i = 0; i < (xSize / 4); i++)
                {
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EAX
                        });
                    Core.AssemblerCode.Add(new Mov {
                            DestinationReg = Registers.EBX, DestinationIndirect = true, DestinationDisplacement = (int)((i * 4)), SourceReg = Registers.EAX
                        });
                }

                switch (xSize % 4)
                {
                case 1:
                {
                    Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                    Core.AssemblerCode.Add(new Mov {
                                DestinationReg = Registers.EBX, DestinationIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4), SourceReg = Registers.AL, Size = 8
                            });
                    break;
                }

                case 2:
                {
                    Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                    Core.AssemblerCode.Add(new Mov {
                                DestinationReg = Registers.EBX, DestinationIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4), SourceReg = Registers.AX, Size = 16
                            });
                    break;
                }

                case 3:
                {
                    Core.AssemblerCode.Add(new Pop {
                                DestinationReg = Registers.EAX
                            });
                    Core.AssemblerCode.Add(new Mov {
                                DestinationReg = Registers.EBX, DestinationIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4), SourceReg = Registers.AX, Size = 16
                            });
                    Core.AssemblerCode.Add(new ShiftRight {
                                DestinationReg = Registers.EAX, SourceRef = "0x10"
                            });
                    Core.AssemblerCode.Add(new Mov {
                                DestinationReg = Registers.EBX, DestinationIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4) + 2, SourceReg = Registers.AL, Size = 8
                            });
                    break;
                }

                case 0:
                {
                    break;
                }

                default:
                    throw new Exception("@Stfld: Remainder size " + (xSize % 4) + " not supported!");
                }

                Core.AssemblerCode.Add(new Add {
                        DestinationReg = Registers.ESP, SourceRef = "0x4"
                    });
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }

            Core.vStack.Pop();
        }
Exemple #30
0
        public override void Execute(ILOpCode instr, MethodBase aMethod)
        {
            var xOpType = ((OpType)instr).Value;
            var xSize   = xOpType.SizeOf().Align();
            var xTypeID = ILHelper.GetTypeID(xOpType);

            /*
             *  A value type is pushed onto the stack.
             *  The value type is popped from the stack; the box operation is performed.
             *  An object reference to the resulting "boxed" value type is pushed onto the stack.
             */
            switch (ILCompiler.CPUArchitecture)
            {
                #region _x86_
            case CPUArch.x86:
            {
                        #warning Have to check memory allocation here, so don't use it now
                //Why i did this? well box is nothing but it converts object type so, lets assume it is already what we want :P
                Console.WriteLine("Box Operation is being called by " + aMethod.FullName() + "\n" + xOpType);
                break;
                throw new Exception("Not yet implemented");
                //***What we are going to do is***
                //1) Push the size of object + 0xC --> The 0xC is the offset of object data before this object metadata is stored
                //2) Call our memory manager
                //3) After that we have done boxing :P
                Core.AssemblerCode.Add(new Push {
                        DestinationRef = "0x" + (0xC + xSize).ToString("X")
                    });
                Core.AssemblerCode.Add(new Call(Helper.lblHeap, true));
                Core.AssemblerCode.Add(new Pop {
                        DestinationReg = Registers.EAX
                    });
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.EAX, DestinationIndirect = true, SourceRef = "0x" + xTypeID.ToString("X")
                    });
                Core.AssemblerCode.Add(new Mov {
                        DestinationReg = Registers.EAX, DestinationIndirect = true, DestinationDisplacement = 4, SourceRef = "0x3"
                    });

                for (int i = 0; i < (xSize / 4); i++)
                {
                    Core.AssemblerCode.Add(new Pop {
                            DestinationReg = Registers.EDX
                        });
                    Core.AssemblerCode.Add(new Mov {
                            DestinationReg = Registers.EAX, DestinationIndirect = true, DestinationDisplacement = (0xC + (i * 4)), SourceReg = Registers.EDX
                        });
                }
                Core.AssemblerCode.Add(new Push {
                        DestinationReg = Registers.EAX
                    });
            }
            break;

                #endregion
                #region _x64_
            case CPUArch.x64:
            {
            }
            break;

                #endregion
                #region _ARM_
            case CPUArch.ARM:
            {
            }
            break;
                #endregion
            }

            Core.vStack.Pop();
            Core.vStack.Push(4, typeof(UIntPtr));
        }