Cosmos/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Ldarg.cs
Trivalik_cp 8cd3d9cf47 GDB Client, change function label to textbox, allows to copy the name
change filesystem to int64, logical error in Read()
fix Ldarg, Ldarga xExtraSize, now should work really 64 bit and greater
2011-06-16 20:56:22 +00:00

117 lines
No EOL
4.3 KiB
C#

using System;
using Cosmos.IL2CPU.ILOpCodes;
using Cosmos.IL2CPU.X86;
using Cosmos.Compiler.Assembler;
using Cosmos.Compiler.Assembler.X86;
namespace Cosmos.IL2CPU.X86.IL
{
[Cosmos.IL2CPU.OpCode( ILOpCode.Code.Ldarg )]
public class Ldarg : ILOp
{
public Ldarg( Cosmos.Compiler.Assembler.Assembler aAsmblr )
: base( aAsmblr )
{
}
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
{
var xOpVar = (OpVar)aOpCode;
DoExecute(Assembler, aMethod, xOpVar.Value);
}
public static int GetArgumentDisplacement(MethodInfo aMethod, ushort aParam) {
var xMethodBase = aMethod.MethodBase;
if (aMethod.PluggedMethod != null) {
xMethodBase = aMethod.PluggedMethod.MethodBase;
}
var xMethodInfo = xMethodBase as System.Reflection.MethodInfo;
uint xReturnSize = 0;
if (xMethodInfo != null) {
xReturnSize = Align(SizeOfType(xMethodInfo.ReturnType), 4);
}
uint xOffset = 8;
var xCorrectedOpValValue = aParam;
if (!aMethod.MethodBase.IsStatic && aParam > 0) {
// if the method has a $this, the OpCode value includes the this at index 0, but GetParameters() doesnt include the this
xCorrectedOpValValue -= 1;
}
var xParams = xMethodBase.GetParameters();
if (aParam == 0 && !xMethodBase.IsStatic) {
// return the this parameter, which is not in .GetParameters()
uint xCurArgSize;
if (xMethodBase.DeclaringType.IsValueType)
{
// value types get a reference passed to the actual value, so pointer:
xCurArgSize = 4;
}
else
{
xCurArgSize = Align(SizeOfType(xMethodBase.DeclaringType), 4);
}
for (int i = xParams.Length - 1; i >= aParam; i--) {
var xSize = Align(SizeOfType(xParams[i].ParameterType), 4);
xOffset += xSize;
}
if (xReturnSize > xCurArgSize) {
uint xExtraSize = xReturnSize - xCurArgSize;
xOffset += xExtraSize;
}
return (int)(xOffset + xCurArgSize - 4);
} else {
for (int i = xParams.Length - 1; i > xCorrectedOpValValue; i--) {
var xSize = Align(SizeOfType(xParams[i].ParameterType), 4);
xOffset += xSize;
}
var xCurArgSize = Align(SizeOfType(xParams[xCorrectedOpValValue].ParameterType), 4);
uint xArgSize = 0;
foreach (var xParam in xParams) {
xArgSize += Align(SizeOfType(xParam.ParameterType), 4);
}
xReturnSize = 0;
if (xReturnSize > xArgSize) {
uint xExtraSize = xReturnSize - xArgSize;
xOffset += xExtraSize;
}
return (int)(xOffset + xCurArgSize - 4);
}
}
public static void DoExecute(Assembler Assembler, MethodInfo aMethod, ushort aParam) {
uint xArgSize = 0u;
var xDisplacement = GetArgumentDisplacement(aMethod, aParam);
Type xArgType;
if (aMethod.MethodBase.IsStatic) {
xArgType = aMethod.MethodBase.GetParameters()[aParam].ParameterType;
} else {
if (aParam == 0u) {
xArgType = aMethod.MethodBase.DeclaringType;
if (xArgType.IsValueType)
{
xArgType = xArgType.MakeByRefType();
}
} else {
xArgType = aMethod.MethodBase.GetParameters()[aParam - 1].ParameterType;
}
}
new Comment("Ldarg");
new Comment("Arg idx = " + aParam);
xArgSize = Align(SizeOfType(xArgType), 4);
new Comment("Arg type = " + xArgType.ToString());
new Comment("Arg size = " + xArgSize);
for (int i = 0; i < (xArgSize / 4); i++) {
new Push {
DestinationReg = Registers.EBP,
DestinationIsIndirect = true,
DestinationDisplacement = (int)(xDisplacement - (i * 4))
};
}
Assembler.Stack.Push(xArgSize, xArgType);
}
}
}