From 92e025ce912200bd0209047c8f70f88196433978 Mon Sep 17 00:00:00 2001 From: cipher_cp <821fea98d6bc9380c58b8952f0c812fba5990545qNDTEvJk> Date: Thu, 26 Jun 2008 08:47:47 +0000 Subject: [PATCH] Fix issue with 64bit arguments --- source/Indy.IL2CPU.IL.X86/Newobj.cs | 421 +++++++++++++++------------- 1 file changed, 223 insertions(+), 198 deletions(-) diff --git a/source/Indy.IL2CPU.IL.X86/Newobj.cs b/source/Indy.IL2CPU.IL.X86/Newobj.cs index 687b39f36..6a69650bb 100644 --- a/source/Indy.IL2CPU.IL.X86/Newobj.cs +++ b/source/Indy.IL2CPU.IL.X86/Newobj.cs @@ -7,206 +7,231 @@ using Indy.IL2CPU.Assembler.X86; using CPU = Indy.IL2CPU.Assembler; using CPUx86 = Indy.IL2CPU.Assembler.X86; using Asm = Indy.IL2CPU.Assembler; -using Assembler=Indy.IL2CPU.Assembler.Assembler; +using Assembler = Indy.IL2CPU.Assembler.Assembler; -namespace Indy.IL2CPU.IL.X86 { - [OpCode(OpCodeEnum.Newobj, false)] - public class Newobj : Op { - public MethodBase CtorDef; - public string CurrentLabel; - public int ILOffset; - public MethodInformation MethodInformation; +namespace Indy.IL2CPU.IL.X86 +{ + [OpCode(OpCodeEnum.Newobj, false)] + public class Newobj : Op + { + public MethodBase CtorDef; + public string CurrentLabel; + public int ILOffset; + public MethodInformation MethodInformation; - public Newobj(ILReader aReader, - MethodInformation aMethodInfo) - : base(aReader, - aMethodInfo) { - CtorDef = aReader.OperandValueMethod; - CurrentLabel = GetInstructionLabel(aReader); - MethodInformation = aMethodInfo; - ILOffset = aReader.Position; - } + public Newobj(ILReader aReader, + MethodInformation aMethodInfo) + : base(aReader, + aMethodInfo) + { + CtorDef = aReader.OperandValueMethod; + CurrentLabel = GetInstructionLabel(aReader); + MethodInformation = aMethodInfo; + ILOffset = aReader.Position; + } - public override void DoAssemble() { - Assemble(Assembler, - CtorDef, - Engine.RegisterType(CtorDef.DeclaringType), - CurrentLabel, - MethodInformation, - ILOffset); - } + public override void DoAssemble() + { + Assemble(Assembler, + CtorDef, + Engine.RegisterType(CtorDef.DeclaringType), + CurrentLabel, + MethodInformation, + ILOffset); + } - public static void Assemble(Assembler.Assembler aAssembler, - MethodBase aCtorDef, - int aTypeId, - string aCurrentLabel, - MethodInformation aCurrentMethodInformation, - int aCurrentILOffset) { - if (aCtorDef != null) { - Engine.QueueMethod(aCtorDef); - } else { - throw new ArgumentNullException("aCtorDef"); - } - var xTypeInfo = Engine.GetTypeInfo(aCtorDef.DeclaringType); - MethodInformation xCtorInfo = Engine.GetMethodInfo(aCtorDef, - aCtorDef, - Label.GenerateLabelName(aCtorDef), - Engine.GetTypeInfo(aCtorDef.DeclaringType), - aCurrentMethodInformation.DebugMode); - if (xTypeInfo.NeedsGC) { - int xObjectSize = ObjectUtilities.GetObjectStorageSize(aCtorDef.DeclaringType); - for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - aAssembler.StackContents.Pop(); - } - Engine.QueueMethod(GCImplementationRefs.AllocNewObjectRef); - Engine.QueueMethod(GCImplementationRefs.IncRefCountRef); - int xExtraSize = 20; - new Pushd("0" + (xObjectSize + xExtraSize).ToString("X").ToUpper() + "h"); - new Assembler.X86.Call(Label.GenerateLabelName(GCImplementationRefs.AllocNewObjectRef)); - Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef); - //new CPUx86.Pushd(CPUx86.Registers.EAX); - new Test(Registers.ECX, - 2); - //new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_1"); - //for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - // new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); - //} - //new CPUx86.Add("esp", "4"); - //Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_1", false); - //new CPU.Label(aCurrentLabel + "_NO_ERROR_1"); - new Pushd(Registers.AtESP); - new Pushd(Registers.AtESP); - new Pushd(Registers.AtESP); - new Pushd(Registers.AtESP); - new Assembler.X86.Call(Label.GenerateLabelName(GCImplementationRefs.IncRefCountRef)); - //new CPUx86.Test("ecx", "2"); - //new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_2"); - //for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - // new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); - //} - //new CPUx86.Add("esp", "16"); - //Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_2", false); - //new CPU.Label(aCurrentLabel + "_NO_ERROR_2"); - new Assembler.X86.Call(Label.GenerateLabelName(GCImplementationRefs.IncRefCountRef)); - //new CPUx86.Test("ecx", "2"); - //new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_3"); - //for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - // new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); - //} - //new CPUx86.Add("esp", "12"); - //Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_3", false); - //new CPU.Label(aCurrentLabel + "_NO_ERROR_3"); - int xObjSize = 0; - int xGCFieldCount = (from item in Engine.GetTypeFieldInfo(aCtorDef, - out xObjSize).Values - where item.NeedsGC - select item).Count(); - new Assembler.X86.Pop(Registers.EAX); - new Move("dword", - Registers.AtEAX, - "0" + aTypeId.ToString("X") + "h"); - new Move("dword", - "[eax + 4]", - "0" + InstanceTypeEnum.NormalObject.ToString("X") + "h"); - new Move("dword", - "[eax + 8]", - "0x" + xGCFieldCount.ToString("X")); - int xSize = (from item in xCtorInfo.Arguments - select item.Size + (item.Size % 4 == 0 - ? 0 - : (4 - (item.Size % 4)))).Take(xCtorInfo.Arguments.Length - 1).Sum(); - for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - new Pushd("[esp + 0x" + (xSize + 4).ToString("X") + "]"); - } - new Assembler.X86.Call(Label.GenerateLabelName(aCtorDef)); - new Test(Registers.ECX, - 2); - new JumpIfEqual(aCurrentLabel + "_NO_ERROR_4"); - for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - new Assembler.X86.Add(Registers.ESP, - (xCtorInfo.Arguments[i].Size % 4 == 0 - ? xCtorInfo.Arguments[i].Size - : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); - } - new Assembler.X86.Add(Registers.ESP, - "4"); - foreach (StackContent xStackInt in aAssembler.StackContents) { - new Assembler.X86.Add(Registers.ESP, - xStackInt.Size.ToString()); - } - Call.EmitExceptionLogic(aAssembler, - aCurrentILOffset, - aCurrentMethodInformation, - aCurrentLabel + "_NO_ERROR_4", - false, - null); - new Label(aCurrentLabel + "_NO_ERROR_4"); - new Assembler.X86.Pop(Registers.EAX); - // aAssembler.StackSizes.Pop(); - // new CPUx86.Add(CPUx86.Registers.ESP, "4"); - for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { - new Assembler.X86.Add(Registers.ESP, - (xCtorInfo.Arguments[i].Size % 4 == 0 - ? xCtorInfo.Arguments[i].Size - : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); - } - new Push(Registers.EAX); - aAssembler.StackContents.Push(new StackContent(4, - aCtorDef.DeclaringType)); - }else { - int xSize = xTypeInfo.StorageSize; - if(xSize % 4 != 0) { - xSize += 4 - (xSize % 4); - } - new CPUx86.Move("eax", - "esp"); - for(int i = 0; i < xSize / 4;i++) { - new CPUx86.Push("0"); - } - new CPUx86.Push("esp"); - int xArgSize = (from item in xCtorInfo.Arguments - select item.Size + (item.Size % 4 == 0 - ? 0 - : (4 - (item.Size % 4)))).Take(xCtorInfo.Arguments.Length - 1).Sum(); - if (xArgSize < xSize) { - throw new NotImplementedException("Support for creating new structs using a ctor which argument size is less than the struct size is not yet supported!"); } - xArgSize += xSize + 4; - for (int i = 1; i < xCtorInfo.Arguments.Length; i++) - { - new Pushd("[esp + 0x" + (xArgSize + 4).ToString("X") + "]"); - } - new Assembler.X86.Call(Label.GenerateLabelName(aCtorDef)); - new Test(Registers.ECX, - 2); - new JumpIfEqual(aCurrentLabel + "_NO_ERROR_4"); - for (int i = 1; i < xCtorInfo.Arguments.Length; i++) - { - new Assembler.X86.Add(Registers.ESP, - (xCtorInfo.Arguments[i].Size % 4 == 0 - ? xCtorInfo.Arguments[i].Size - : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); - } - new Assembler.X86.Add(Registers.ESP, - "4"); - foreach (StackContent xStackInt in aAssembler.StackContents) - { - new Assembler.X86.Add(Registers.ESP, - xStackInt.Size.ToString()); - } - Call.EmitExceptionLogic(aAssembler, - aCurrentILOffset, - aCurrentMethodInformation, - aCurrentLabel + "_NO_ERROR_4", - false, - null); - new Label(aCurrentLabel + "_NO_ERROR_4"); - // at this point, there's the normal arguments on the stack, and the newly created object value - for(int i = 0; i < xSize /4;i++) { - new CPUx86.Pop("eax"); - new CPUx86.Move("[esp + " + (xArgSize + i * 4) + "]", - "eax"); - } - } - } - } + public static void Assemble(Assembler.Assembler aAssembler, + MethodBase aCtorDef, + int aTypeId, + string aCurrentLabel, + MethodInformation aCurrentMethodInformation, + int aCurrentILOffset) + { + if (aCtorDef != null) + { + Engine.QueueMethod(aCtorDef); + } + else + { + throw new ArgumentNullException("aCtorDef"); + } + var xTypeInfo = Engine.GetTypeInfo(aCtorDef.DeclaringType); + MethodInformation xCtorInfo = Engine.GetMethodInfo(aCtorDef, + aCtorDef, + Label.GenerateLabelName(aCtorDef), + Engine.GetTypeInfo(aCtorDef.DeclaringType), + aCurrentMethodInformation.DebugMode); + if (xTypeInfo.NeedsGC) + { + int xObjectSize = ObjectUtilities.GetObjectStorageSize(aCtorDef.DeclaringType); + for (int i = 1; i < xCtorInfo.Arguments.Length; i++) + { + aAssembler.StackContents.Pop(); + } + Engine.QueueMethod(GCImplementationRefs.AllocNewObjectRef); + Engine.QueueMethod(GCImplementationRefs.IncRefCountRef); + int xExtraSize = 20; + new Pushd("0" + (xObjectSize + xExtraSize).ToString("X").ToUpper() + "h"); + new Assembler.X86.Call(Label.GenerateLabelName(GCImplementationRefs.AllocNewObjectRef)); + Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef); + //new CPUx86.Pushd(CPUx86.Registers.EAX); + new Test(Registers.ECX, + 2); + //new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_1"); + //for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { + // new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); + //} + //new CPUx86.Add("esp", "4"); + //Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_1", false); + //new CPU.Label(aCurrentLabel + "_NO_ERROR_1"); + new Pushd(Registers.AtESP); + new Pushd(Registers.AtESP); + new Pushd(Registers.AtESP); + new Pushd(Registers.AtESP); + new Assembler.X86.Call(Label.GenerateLabelName(GCImplementationRefs.IncRefCountRef)); + //new CPUx86.Test("ecx", "2"); + //new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_2"); + //for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { + // new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); + //} + //new CPUx86.Add("esp", "16"); + //Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_2", false); + //new CPU.Label(aCurrentLabel + "_NO_ERROR_2"); + new Assembler.X86.Call(Label.GenerateLabelName(GCImplementationRefs.IncRefCountRef)); + //new CPUx86.Test("ecx", "2"); + //new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_3"); + //for (int i = 1; i < xCtorInfo.Arguments.Length; i++) { + // new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); + //} + //new CPUx86.Add("esp", "12"); + //Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_3", false); + //new CPU.Label(aCurrentLabel + "_NO_ERROR_3"); + int xObjSize = 0; + int xGCFieldCount = (from item in Engine.GetTypeFieldInfo(aCtorDef, + out xObjSize).Values + where item.NeedsGC + select item).Count(); + new Assembler.X86.Pop(Registers.EAX); + new Move("dword", + Registers.AtEAX, + "0" + aTypeId.ToString("X") + "h"); + new Move("dword", + "[eax + 4]", + "0" + InstanceTypeEnum.NormalObject.ToString("X") + "h"); + new Move("dword", + "[eax + 8]", + "0x" + xGCFieldCount.ToString("X")); + int xSize = (from item in xCtorInfo.Arguments + select item.Size + (item.Size % 4 == 0 + ? 0 + : (4 - (item.Size % 4)))).Take(xCtorInfo.Arguments.Length - 1).Sum(); + for (int i = 1; i < xCtorInfo.Arguments.Length; i++) + { + new Comment(String.Format("Arg {0}: {1}", i, xCtorInfo.Arguments[i].Size)); + for (int j = 0; j < xCtorInfo.Arguments[i].Size; j += 4) + { + new Pushd("[esp + 0x" + (xSize + 4).ToString("X") + "]"); + } + } + new Assembler.X86.Call(Label.GenerateLabelName(aCtorDef)); + new Test(Registers.ECX, + 2); + new JumpIfEqual(aCurrentLabel + "_NO_ERROR_4"); + for (int i = 1; i < xCtorInfo.Arguments.Length; i++) + { + new Assembler.X86.Add(Registers.ESP, + (xCtorInfo.Arguments[i].Size % 4 == 0 + ? xCtorInfo.Arguments[i].Size + : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); + } + new Assembler.X86.Add(Registers.ESP, + "4"); + foreach (StackContent xStackInt in aAssembler.StackContents) + { + new Assembler.X86.Add(Registers.ESP, + xStackInt.Size.ToString()); + } + Call.EmitExceptionLogic(aAssembler, + aCurrentILOffset, + aCurrentMethodInformation, + aCurrentLabel + "_NO_ERROR_4", + false, + null); + new Label(aCurrentLabel + "_NO_ERROR_4"); + new Assembler.X86.Pop(Registers.EAX); + // aAssembler.StackSizes.Pop(); + // new CPUx86.Add(CPUx86.Registers.ESP, "4"); + for (int i = 1; i < xCtorInfo.Arguments.Length; i++) + { + new Assembler.X86.Add(Registers.ESP, + (xCtorInfo.Arguments[i].Size % 4 == 0 + ? xCtorInfo.Arguments[i].Size + : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); + } + new Push(Registers.EAX); + aAssembler.StackContents.Push(new StackContent(4, + aCtorDef.DeclaringType)); + } + else + { + int xSize = xTypeInfo.StorageSize; + if (xSize % 4 != 0) + { + xSize += 4 - (xSize % 4); + } + new CPUx86.Move("eax", + "esp"); + for (int i = 0; i < xSize / 4; i++) + { + new CPUx86.Push("0"); + } + new CPUx86.Push("esp"); + int xArgSize = (from item in xCtorInfo.Arguments + select item.Size + (item.Size % 4 == 0 + ? 0 + : (4 - (item.Size % 4)))).Take(xCtorInfo.Arguments.Length - 1).Sum(); + if (xArgSize < xSize) + { + throw new NotImplementedException("Support for creating new structs using a ctor which argument size is less than the struct size is not yet supported!"); + } + xArgSize += xSize + 4; + for (int i = 1; i < xCtorInfo.Arguments.Length; i++) + { + new Pushd("[esp + 0x" + (xArgSize + 4).ToString("X") + "]"); + } + new Assembler.X86.Call(Label.GenerateLabelName(aCtorDef)); + new Test(Registers.ECX, + 2); + new JumpIfEqual(aCurrentLabel + "_NO_ERROR_4"); + for (int i = 1; i < xCtorInfo.Arguments.Length; i++) + { + new Assembler.X86.Add(Registers.ESP, + (xCtorInfo.Arguments[i].Size % 4 == 0 + ? xCtorInfo.Arguments[i].Size + : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString()); + } + new Assembler.X86.Add(Registers.ESP, + "4"); + foreach (StackContent xStackInt in aAssembler.StackContents) + { + new Assembler.X86.Add(Registers.ESP, + xStackInt.Size.ToString()); + } + Call.EmitExceptionLogic(aAssembler, + aCurrentILOffset, + aCurrentMethodInformation, + aCurrentLabel + "_NO_ERROR_4", + false, + null); + new Label(aCurrentLabel + "_NO_ERROR_4"); + // at this point, there's the normal arguments on the stack, and the newly created object value + for (int i = 0; i < xSize / 4; i++) + { + new CPUx86.Pop("eax"); + new CPUx86.Move("[esp + " + (xArgSize + i * 4) + "]", + "eax"); + } + } + } + } } \ No newline at end of file