Cosmos/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Ldarga.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

202 lines
No EOL
8.6 KiB
C#

using System;
using CPUx86 = Cosmos.Compiler.Assembler.X86;
using Cosmos.Compiler.Assembler;
using Cosmos.IL2CPU.ILOpCodes;
using Cosmos.Compiler.Assembler.X86;
namespace Cosmos.IL2CPU.X86.IL
{
[Cosmos.IL2CPU.OpCode( ILOpCode.Code.Ldarga )]
public class Ldarga : ILOp
{
public Ldarga( Cosmos.Compiler.Assembler.Assembler aAsmblr )
: base( aAsmblr )
{
}
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()
var 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);
}
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);
}
}
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
{
var xOpVar = (OpVar)aOpCode;
var xDisplacement = Ldarga.GetArgumentDisplacement(aMethod, xOpVar.Value);
new Move {DestinationReg=RegistersEnum.EBX, SourceValue = (uint)(xDisplacement) };
new Move{DestinationReg = RegistersEnum.EAX, SourceReg = RegistersEnum.EBP };
new CPUx86.Add { DestinationReg = RegistersEnum.EAX, SourceReg = RegistersEnum.EBX };
new CPUx86.Push { DestinationReg = RegistersEnum.EAX };
Assembler.Stack.Push(4, typeof(uint));
// if (aMethod.MethodBase.DeclaringType.FullName == "Cosmos.Kernel.Plugs.Console"
// && aMethod.MethodBase.Name == "Write"
// && aMethod.MethodBase.GetParameters()[0].ParameterType == typeof(int))
// {
// Console.Write("");
// }
// Cosmos.IL2CPU.ILOpCodes.OpVar xOpVar = ( Cosmos.IL2CPU.ILOpCodes.OpVar )aOpCode;
// var xMethodInfo = aMethod.MethodBase as System.Reflection.MethodInfo;
// uint xReturnSize = 0;
// if( xMethodInfo != null )
// {
// xReturnSize = Align( SizeOfType( xMethodInfo.ReturnType ), 4 );
// }
// uint xOffset = 8;
// var xCorrectedOpValValue = xOpVar.Value;
// if( !aMethod.MethodBase.IsStatic && xOpVar.Value > 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 = aMethod.MethodBase.GetParameters();
// 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;
// uint xExtraSize = 0;
// if( xReturnSize > xArgSize )
// {
// xExtraSize = xArgSize - xReturnSize;
// }
// xOffset += xExtraSize;
//#warning TODO: check this
// new CPUx86.Push { DestinationReg = CPUx86.Registers.EBP };
// for( int i = 0; i < ( xCurArgSize / 4 ); i++ )
// {
// new CPUx86.Push { DestinationValue = ( uint )( xCurArgSize - ( ( i + 1 ) * 4 ) ) };
// }
// Assembler.Stack.Push( ( int )xCurArgSize, xParams[ xCorrectedOpValValue ].ParameterType );
// //for( int i = 0; i < ( mSize / 4 ); i++ )
// //{
// // mVirtualAddresses[ i ] = ( mOffset + ( ( i + 1 ) * 4 ) + 4 );
// //}
// //mAddress = aMethodInfo.Arguments[ aIndex ].VirtualAddresses.First();
// Assembler.Stack.Push( new StackContents.Item( 4, typeof( uint ) ) );
// //new CPUx86.Push { DestinationValue = ( uint )mAddress };
// //
// Assembler.Stack.Push( new StackContents.Item( 4, typeof( uint ) ) );
// new Add( Assembler ).Execute( aMethod, aOpCode );
}
// using System;
// using System.Linq;
//
//
// using CPU = Cosmos.Compiler.Assembler.X86;
// using Cosmos.IL2CPU.X86;
//
// namespace Cosmos.IL2CPU.IL.X86 {
// [OpCode(OpCodeEnum.Ldarga)]
// public class Ldarga: Op {
// private int mAddress;
// private string mNextLabel;
// private string mCurLabel;
// private uint mCurOffset;
// private MethodInformation mMethodInformation;
// protected void SetArgIndex(int aIndex, MethodInformation aMethodInfo) {
// mAddress = aMethodInfo.Arguments[aIndex].VirtualAddresses.First();
// }
// public Ldarga(MethodInformation aMethodInfo, int aIndex, string aCurrentLabel, uint aCurrentOffset, string aNextLabel)
// : base(null, aMethodInfo) {
// SetArgIndex(aIndex, aMethodInfo);
//
// mMethodInformation = aMethodInfo;
// mCurOffset = aCurrentOffset;
// mCurLabel = aCurrentLabel;
// mNextLabel = aNextLabel;
// }
//
// public Ldarga(ILReader aReader, MethodInformation aMethodInfo)
// : base(aReader, aMethodInfo) {
// if (aReader != null) {
// SetArgIndex(aReader.OperandValueInt32, aMethodInfo);
// //ParameterDefinition xParam = aReader.Operand as ParameterDefinition;
// //if (xParam != null) {
// // SetArgIndex(xParam.Sequence - 1, aMethodInfo);
// //}
// }
// mMethodInformation = aMethodInfo;
// mCurOffset = aReader.Position;
// mCurLabel = IL.Op.GetInstructionLabel(aReader);
// mNextLabel = IL.Op.GetInstructionLabel(aReader.NextPosition);
// }
// public override void DoAssemble() {
// new CPU.Push { DestinationReg = CPU.Registers.EBP };
// Assembler.Stack.Push(new StackContent(4, typeof(uint)));
// new CPU.Push { DestinationValue = (uint)mAddress };
// Assembler.Stack.Push(new StackContent(4, typeof(uint)));
// Add(Assembler, GetServiceProvider(), mCurLabel, mMethodInformation, mCurOffset, mNextLabel);
// }
// }
// }
}
}