using System; using System.Linq; using Indy.IL2CPU.Assembler; using Indy.IL2CPU.Assembler.X86; using CPUx86 = Indy.IL2CPU.Assembler.X86; using Indy.IL2CPU.Compiler; namespace Indy.IL2CPU.IL.X86 { public class X86MethodFooterOp : MethodFooterOp { public readonly uint TotalArgsSize = 0; public readonly uint ReturnSize = 0; public readonly MethodInformation.Variable[] Locals; public readonly MethodInformation.Argument[] Args; public readonly bool DebugMode; public readonly bool MethodIsNonDebuggable; public readonly int LocAllocItemCount; public X86MethodFooterOp(ILReader aReader, MethodInformation aMethodInfo) : base(aReader, aMethodInfo) { if (aMethodInfo != null) { // if (aMethodInfo.Locals.Length > 0) { // TotalLocalsSize += aMethodInfo.Locals[aMethodInfo.Locals.Length - 1].Offset + aMethodInfo.Locals[aMethodInfo.Locals.Length - 1].Size; // } Locals = aMethodInfo.Locals.ToArray(); Args = aMethodInfo.Arguments.ToArray(); ReturnSize = aMethodInfo.ReturnSize; DebugMode = aMethodInfo.DebugMode; MethodIsNonDebuggable = aMethodInfo.IsNonDebuggable; LocAllocItemCount = 0; //if (aMethodInfo.MethodData.ContainsKey(Localloc.LocAllocCountMethodDataEntry)) { // LocAllocItemCount = (int)aMethodInfo.MethodData[Localloc.LocAllocCountMethodDataEntry]; //} } } public override void DoAssemble() { //uint xArgSize = 0; //foreach (var xItem in Args) { // xArgSize += xItem.Size; //} //var xDecRefInfo = GetService().GetMethodInfo(GCImplementationRefs.DecRefCountRef, // false); //var xHeapFreeInfo = // GetService().GetMethodInfo(typeof (RuntimeEngine).GetMethod("Heap_Free"), false); //AssembleFooter(ReturnSize, Assembler, Locals, Args, xArgSize, DebugMode, MethodIsNonDebuggable, // (uint) LocAllocItemCount, GetService().SizeOfType, // xDecRefInfo.LabelName, xHeapFreeInfo.LabelName); } public static void AssembleFooter(uint aReturnSize, Assembler.Assembler aAssembler, MethodInformation.Variable[] aLocals, MethodInformation.Argument[] aArgs, uint aTotalArgsSize, bool aDebugMode, bool aIsNonDebuggable, uint aLocAllocItemCount, Func aGetStorageSizeDelegate, string aDecRefLabel, string aHeapFreeLabel) { //uint xReturnSize = aReturnSize; //if (xReturnSize % 4 > 0) //{ // xReturnSize += 4 - xReturnSize % 4; //} //new Label(EndOfMethodLabelNameNormal); //new CPUx86.Move { DestinationReg = CPUx86.Registers.ECX, SourceValue = 0 }; //if (aReturnSize > 0) //{ // //var xArgSize = (from item in aArgs // // let xSize = item.Size + item.Offset // // select xSize).FirstOrDefault(); // //new Comment(String.Format("ReturnSize = {0}, ArgumentSize = {1}", // // aReturnSize, // // xArgSize)); // //int xOffset = 4; // //if(xArgSize>0) { // // xArgSize -= xReturnSize; // // xOffset = xArgSize; // //} // int xOffset = 4; // if (aArgs.Length > 0) // { // // old code: // //xOffset = aArgs.First().Offset + 4; // //if (xOffset < 0) // //{ // // xOffset = 0; // //} // // new code: // xOffset = (int)((from item in aArgs // select item.Offset + item.Size).First()); // } // for (int i = 0; i < xReturnSize / 4; i++) // { // new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; // new CPUx86.Move { // DestinationReg = CPUx86.Registers.EBP, // DestinationIsIndirect = true, // DestinationDisplacement = (int)(xOffset + ((i + 1) * 4) + 4 - xReturnSize), // SourceReg = Registers.EAX // }; // } //} //new CPUx86.Jump { DestinationLabel = EndOfMethodLabelNameException }; //new Label(EndOfMethodLabelNameException); //for (int i = 0; i < aLocAllocItemCount;i++ ) //{ // new CPUx86.Call { DestinationLabel = aHeapFreeLabel }; //} //if (aDebugMode && aIsNonDebuggable) //{ // new CPUx86.Call { DestinationLabel = "DebugPoint_DebugResume" }; //} //if ((from xLocal in aLocals // where xLocal.IsReferenceType // select 1).Count() > 0 || (from xArg in aArgs // where xArg.IsReferenceType // select 1).Count() > 0) { // new CPUx86.Push { DestinationReg = Registers.ECX }; // foreach (MethodInformation.Variable xLocal in aLocals) { // if (xLocal.IsReferenceType) { // Op.Ldloc(aAssembler, // xLocal, // false, // aGetStorageSizeDelegate(xLocal.VariableType)); // new CPUx86.Call { DestinationLabel = aDecRefLabel }; // } // } // foreach (MethodInformation.Argument xArg in aArgs) { // if (xArg.IsReferenceType) { // Op.Ldarg(aAssembler, // xArg, // false); // //, aGetStorageSizeDelegate(xArg.ArgumentType) // new CPUx86.Call { DestinationLabel = aDecRefLabel }; // } // } // new CPUx86.Pop { DestinationReg = CPUx86.Registers.ECX }; //} //for (int j = aLocals.Length - 1; j >= 0; j--) //{ // int xLocalSize = aLocals[j].Size; // new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xLocalSize }; //} ////new CPUx86.Add(CPUx86.Registers_Old.ESP, "0x4"); //new CPUx86.Pop { DestinationReg = CPUx86.Registers.EBP }; //var xRetSize = ((int)aTotalArgsSize) - ((int)xReturnSize); //if(xRetSize<0) { // xRetSize = 0; //} //new CPUx86.Return { DestinationValue = (uint)xRetSize }; } } }