PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/source2/IL2CPU/Cosmos.IL2CPU/IL/Call.cs

https://bitbucket.org/mvptracker/cosmos
C# | 149 lines | 108 code | 11 blank | 30 comment | 24 complexity | 34fa0dceca3ee98b7c4f6a8dfd32c086 MD5 | raw file
Possible License(s): BSD-2-Clause
  1. using System;
  2. using Cosmos.IL2CPU.ILOpCodes;
  3. // using System.Collections.Generic;
  4. // using System.IO;
  5. // using System.Linq;
  6. //
  7. // using IL2CPU=Cosmos.IL2CPU;
  8. using CPU = Cosmos.Assembler.x86;
  9. using CPUx86 = Cosmos.Assembler.x86;
  10. using Cosmos.IL2CPU.X86;
  11. using System.Reflection;
  12. using System.Collections.Generic;
  13. using System.IO;
  14. using Cosmos.Assembler;
  15. // using System.Reflection;
  16. // using Cosmos.IL2CPU.X86;
  17. // using Cosmos.IL2CPU.Compiler;
  18. namespace Cosmos.IL2CPU.X86.IL {
  19. [Cosmos.IL2CPU.OpCode(ILOpCode.Code.Call)]
  20. public class Call: ILOp {
  21. // private string LabelName;
  22. // private uint mResultSize;
  23. // private uint? TotalArgumentSize = null;
  24. // private bool mIsDebugger_Break = false;
  25. // private uint[] ArgumentSizes = new uint[0];
  26. // private MethodInformation mMethodInfo;
  27. // private MethodInformation mTargetMethodInfo;
  28. // private string mNextLabelName;
  29. // private uint mCurrentILOffset;
  30. // private MethodBase mMethod;
  31. public Call(Cosmos.Assembler.Assembler aAsmblr)
  32. : base(aAsmblr) {
  33. }
  34. public static uint GetStackSizeToReservate(MethodBase aMethod) {
  35. var xMethodInfo = aMethod as System.Reflection.MethodInfo;
  36. uint xReturnSize = 0;
  37. if (xMethodInfo != null) {
  38. xReturnSize = SizeOfType(xMethodInfo.ReturnType);
  39. }
  40. if (xReturnSize == 0) {
  41. return 0;
  42. }
  43. // todo: implement exception support
  44. int xExtraStackSize = (int)Align(xReturnSize, 4);
  45. var xParameters = aMethod.GetParameters();
  46. foreach (var xItem in xParameters) {
  47. xExtraStackSize -= (int)Align(SizeOfType(xItem.ParameterType), 4);
  48. }
  49. if (!xMethodInfo.IsStatic) {
  50. xExtraStackSize -= GetNativePointerSize(xMethodInfo);
  51. }
  52. if (xExtraStackSize > 0) {
  53. return (uint)xExtraStackSize;
  54. }
  55. return 0;
  56. }
  57. private static int GetNativePointerSize(System.Reflection.MethodInfo xMethodInfo)
  58. {
  59. // old code, which goof up everything for structs
  60. //return (int)Align(SizeOfType(xMethodInfo.DeclaringType), 4);
  61. // TODO native pointer size, so that COSMOS could be 64 bit OS
  62. return 4;
  63. }
  64. public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) {
  65. var xOpMethod = aOpCode as OpMethod;
  66. DoExecute(Assembler, aMethod, xOpMethod.Value, aOpCode, LabelName.Get(aMethod.MethodBase));
  67. }
  68. public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel)
  69. {
  70. DoExecute(Assembler, aCurrentMethod, aTargetMethod, aCurrent, currentLabel, ILOp.GetLabel(aCurrentMethod, aCurrent.NextPosition));
  71. }
  72. public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, string nextLabel) {
  73. //if (aTargetMethod.IsVirtual) {
  74. // Callvirt.DoExecute(Assembler, aCurrentMethod, aTargetMethod, aTargetMethodUID, aCurrentPosition);
  75. // return;
  76. //}
  77. var xMethodInfo = aTargetMethod as System.Reflection.MethodInfo;
  78. // mTargetMethodInfo = GetService<IMetaDataInfoService>().GetMethodInfo(mMethod
  79. // , mMethod, mMethodDescription, null, mCurrentMethodInfo.DebugMode);
  80. string xNormalAddress = "";
  81. if (aTargetMethod.IsStatic || !aTargetMethod.IsVirtual || aTargetMethod.IsFinal) {
  82. xNormalAddress = LabelName.Get(aTargetMethod);
  83. } else {
  84. xNormalAddress = LabelName.Get(aTargetMethod);
  85. //throw new Exception("Call: non-concrete method called: '" + aTargetMethod.GetFullName() + "'");
  86. }
  87. var xParameters = aTargetMethod.GetParameters();
  88. int xArgCount = xParameters.Length;
  89. // todo: implement exception support
  90. uint xExtraStackSize = GetStackSizeToReservate(aTargetMethod);
  91. if (xExtraStackSize > 0) {
  92. new CPUx86.Sub {
  93. DestinationReg = CPUx86.Registers.ESP,
  94. SourceValue = (uint)xExtraStackSize
  95. };
  96. }
  97. new CPUx86.Call {
  98. DestinationLabel = xNormalAddress
  99. };
  100. uint xReturnSize=0;
  101. if (xMethodInfo != null)
  102. {
  103. xReturnSize = SizeOfType(xMethodInfo.ReturnType);
  104. }
  105. if (aCurrentMethod != null)
  106. {
  107. EmitExceptionLogic(Assembler, aCurrentMethod, aCurrent, true,
  108. delegate()
  109. {
  110. var xResultSize = xReturnSize;
  111. if (xResultSize % 4 != 0)
  112. {
  113. xResultSize += 4 - (xResultSize % 4);
  114. }
  115. for (int i = 0; i < xResultSize / 4; i++)
  116. {
  117. new CPUx86.Add
  118. {
  119. DestinationReg = CPUx86.Registers.ESP,
  120. SourceValue = 4
  121. };
  122. }
  123. }, nextLabel);
  124. }
  125. for (int i = 0; i < xParameters.Length; i++) {
  126. Assembler.Stack.Pop();
  127. }
  128. if (!aTargetMethod.IsStatic) {
  129. Assembler.Stack.Pop();
  130. }
  131. if (xMethodInfo == null || SizeOfType(xMethodInfo.ReturnType) == 0) {
  132. return;
  133. }
  134. Assembler.Stack.Push(ILOp.Align(SizeOfType(xMethodInfo.ReturnType), 4),
  135. xMethodInfo.ReturnType);
  136. }
  137. }
  138. }