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")); }
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(); }
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(); }
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); }
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)); }
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(); }
#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); }); }
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); }
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(); }
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"); }
/// <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(); }
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(); }
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); }
/// <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(); } }
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"); } } }
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(); } }
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; } }
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 } }
/// <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); }
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)); }
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 } }
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); }
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 } }
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)); }
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 } }
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(); }
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)); }