Reformat code, and add settings to editorconfig file.

This commit is contained in:
Matthijs ter Woord 2015-11-07 10:16:09 +01:00
parent 870c07991a
commit 6f9fcec90a
4 changed files with 431 additions and 206 deletions

View file

@ -21,6 +21,12 @@ indent_size = 2
[IL/Call.cs]
indent_size = 4
[IL/Callvirt.cs]
indent_size = 4
[IL/Newobj.cs]
indent_size = 4
[AppAssembler.cs]
indent_size = 4

View file

@ -16,162 +16,196 @@ using Cosmos.Assembler;
using SysReflection = System.Reflection;
namespace Cosmos.IL2CPU.X86.IL {
[Cosmos.IL2CPU.OpCode(ILOpCode.Code.Call)]
public class Call: ILOp {
// private string LabelName;
// private uint mResultSize;
// private uint? TotalArgumentSize = null;
// private bool mIsDebugger_Break = false;
// private uint[] ArgumentSizes = new uint[0];
// private MethodInformation mMethodInfo;
// private MethodInformation mTargetMethodInfo;
// private string mNextLabelName;
// private uint mCurrentILOffset;
// private MethodBase mMethod;
public Call(Cosmos.Assembler.Assembler aAsmblr)
: base(aAsmblr) {
}
public static uint GetStackSizeToReservate(MethodBase aMethod) {
var xMethodInfo = aMethod as SysReflection.MethodInfo;
uint xReturnSize = 0;
if (xMethodInfo != null) {
xReturnSize = SizeOfType(xMethodInfo.ReturnType);
}
if (xReturnSize == 0) {
return 0;
}
// todo: implement exception support
int xExtraStackSize = (int)Align(xReturnSize, 4);
var xParameters = aMethod.GetParameters();
foreach (var xItem in xParameters) {
xExtraStackSize -= (int)Align(SizeOfType(xItem.ParameterType), 4);
}
if (!xMethodInfo.IsStatic) {
xExtraStackSize -= GetNativePointerSize(xMethodInfo);
}
if (xExtraStackSize > 0) {
return (uint)xExtraStackSize;
}
return 0;
}
private static int GetNativePointerSize(SysReflection.MethodInfo xMethodInfo)
{
// old code, which goof up everything for structs
//return (int)Align(SizeOfType(xMethodInfo.DeclaringType), 4);
// TODO native pointer size, so that COSMOS could be 64 bit OS
return 4;
}
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) {
var xOpMethod = aOpCode as OpMethod;
DoExecute(Assembler, aMethod, xOpMethod.Value, aOpCode, LabelName.Get(aMethod.MethodBase), DebugEnabled);
}
public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, bool debugEnabled)
namespace Cosmos.IL2CPU.X86.IL
{
[Cosmos.IL2CPU.OpCode(ILOpCode.Code.Call)]
public class Call: ILOp
{
DoExecute(Assembler, aCurrentMethod, aTargetMethod, aCurrent, currentLabel, ILOp.GetLabel(aCurrentMethod, aCurrent.NextPosition), debugEnabled);
}
// private string LabelName;
// private uint mResultSize;
// private uint? TotalArgumentSize = null;
// private bool mIsDebugger_Break = false;
// private uint[] ArgumentSizes = new uint[0];
// private MethodInformation mMethodInfo;
// private MethodInformation mTargetMethodInfo;
// private string mNextLabelName;
// private uint mCurrentILOffset;
// private MethodBase mMethod;
public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, string nextLabel, bool debugEnabled) {
//if (aTargetMethod.IsVirtual) {
// Callvirt.DoExecute(Assembler, aCurrentMethod, aTargetMethod, aTargetMethodUID, aCurrentPosition);
// return;
//}
var xMethodInfo = aTargetMethod as SysReflection.MethodInfo;
// mTargetMethodInfo = GetService<IMetaDataInfoService>().GetMethodInfo(mMethod
// , mMethod, mMethodDescription, null, mCurrentMethodInfo.DebugMode);
string xNormalAddress;
if (aTargetMethod.IsStatic || !aTargetMethod.IsVirtual || aTargetMethod.IsFinal) {
xNormalAddress = LabelName.Get(aTargetMethod);
} else {
xNormalAddress = LabelName.Get(aTargetMethod);
//throw new Exception("Call: non-concrete method called: '" + aTargetMethod.GetFullName() + "'");
}
var xParameters = aTargetMethod.GetParameters();
int xArgCount = xParameters.Length;
// todo: implement exception support
uint xExtraStackSize = GetStackSizeToReservate(aTargetMethod);
if (!aTargetMethod.IsStatic && debugEnabled)
public Call(Cosmos.Assembler.Assembler aAsmblr)
: base(aAsmblr)
{
uint xThisOffset = 0;
foreach (var xItem in xParameters)
{
xThisOffset += Align(SizeOfType(xItem.ParameterType), 4);
}
var stackOffsetToCheck = xThisOffset;
DoNullReferenceCheck(Assembler, debugEnabled, stackOffsetToCheck);
}
if (xExtraStackSize > 0) {
new CPUx86.Sub {
DestinationReg = CPUx86.Registers.ESP,
SourceValue = (uint)xExtraStackSize
};
}
new CPUx86.Call {
DestinationLabel = xNormalAddress
};
public static uint GetStackSizeToReservate(MethodBase aMethod)
{
uint xReturnSize=0;
if (xMethodInfo != null)
{
xReturnSize = SizeOfType(xMethodInfo.ReturnType);
}
if (aCurrentMethod != null)
{
EmitExceptionLogic(Assembler, aCurrentMethod, aCurrent, true,
delegate()
{
var xStackOffsetBefore = aCurrent.StackOffsetBeforeExecution;
var xMethodInfo = aMethod as SysReflection.MethodInfo;
uint xReturnSize = 0;
if (xMethodInfo != null)
{
xReturnSize = SizeOfType(xMethodInfo.ReturnType);
}
if (xReturnSize == 0)
{
return 0;
}
uint xPopSize = 0;
foreach (var type in aCurrent.StackPopTypes)
{
xPopSize += Align(SizeOfType(type), 4);
}
// todo: implement exception support
int xExtraStackSize = (int)Align(xReturnSize, 4);
var xParameters = aMethod.GetParameters();
foreach (var xItem in xParameters)
{
xExtraStackSize -= (int)Align(SizeOfType(xItem.ParameterType), 4);
}
if (!xMethodInfo.IsStatic)
{
xExtraStackSize -= GetNativePointerSize(xMethodInfo);
}
if (xExtraStackSize > 0)
{
return (uint)xExtraStackSize;
}
return 0;
}
var xResultSize = xReturnSize;
if (xResultSize % 4 != 0)
{
xResultSize += 4 - (xResultSize % 4);
}
private static int GetNativePointerSize(SysReflection.MethodInfo xMethodInfo)
{
// old code, which goof up everything for structs
//return (int)Align(SizeOfType(xMethodInfo.DeclaringType), 4);
// TODO native pointer size, so that COSMOS could be 64 bit OS
return 4;
}
if (xStackOffsetBefore > (xPopSize + xResultSize))
{
if (xResultSize > 0)
{
new Comment("Cleanup return");
// cleanup result values
for (int i = 0; i < xResultSize / 4; i++)
{
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
}
}
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
{
var xOpMethod = aOpCode as OpMethod;
DoExecute(Assembler, aMethod, xOpMethod.Value, aOpCode, LabelName.Get(aMethod.MethodBase), DebugEnabled);
}
if (xPopSize > 0)
{
var xExtraStack = xStackOffsetBefore - xPopSize - xResultSize;
new Comment("Cleanup extra stack");
// cleanup result values
for (int i = 0; i < xExtraStack / 4; i++)
{
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
}
}
}
}, nextLabel);
public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, bool debugEnabled)
{
DoExecute(Assembler, aCurrentMethod, aTargetMethod, aCurrent, currentLabel, ILOp.GetLabel(aCurrentMethod, aCurrent.NextPosition), debugEnabled);
}
}
if (xMethodInfo == null || SizeOfType(xMethodInfo.ReturnType) == 0) {
return;
}
public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, string nextLabel, bool debugEnabled)
{
//if (aTargetMethod.IsVirtual) {
// Callvirt.DoExecute(Assembler, aCurrentMethod, aTargetMethod, aTargetMethodUID, aCurrentPosition);
// return;
//}
var xMethodInfo = aTargetMethod as SysReflection.MethodInfo;
// mTargetMethodInfo = GetService<IMetaDataInfoService>().GetMethodInfo(mMethod
// , mMethod, mMethodDescription, null, mCurrentMethodInfo.DebugMode);
string xNormalAddress;
if (aTargetMethod.IsStatic
|| !aTargetMethod.IsVirtual
|| aTargetMethod.IsFinal)
{
xNormalAddress = LabelName.Get(aTargetMethod);
}
else
{
xNormalAddress = LabelName.Get(aTargetMethod);
//throw new Exception("Call: non-concrete method called: '" + aTargetMethod.GetFullName() + "'");
}
var xParameters = aTargetMethod.GetParameters();
int xArgCount = xParameters.Length;
// todo: implement exception support
uint xExtraStackSize = GetStackSizeToReservate(aTargetMethod);
if (!aTargetMethod.IsStatic && debugEnabled)
{
uint xThisOffset = 0;
foreach (var xItem in xParameters)
{
xThisOffset += Align(SizeOfType(xItem.ParameterType), 4);
}
var stackOffsetToCheck = xThisOffset;
DoNullReferenceCheck(Assembler, debugEnabled, stackOffsetToCheck);
}
if (xExtraStackSize > 0)
{
new CPUx86.Sub
{
DestinationReg = CPUx86.Registers.ESP,
SourceValue = (uint)xExtraStackSize
};
}
new CPUx86.Call
{
DestinationLabel = xNormalAddress
};
uint xReturnSize = 0;
if (xMethodInfo != null)
{
xReturnSize = SizeOfType(xMethodInfo.ReturnType);
}
if (aCurrentMethod != null)
{
EmitExceptionLogic(Assembler, aCurrentMethod, aCurrent, true,
delegate()
{
var xStackOffsetBefore = aCurrent.StackOffsetBeforeExecution;
uint xPopSize = 0;
foreach (var type in aCurrent.StackPopTypes)
{
xPopSize += Align(SizeOfType(type), 4);
}
var xResultSize = xReturnSize;
if (xResultSize % 4 != 0)
{
xResultSize += 4 - (xResultSize % 4);
}
new Comment("xStackOffsetBefore = " + xStackOffsetBefore);
new Comment("xPopSize = " + xPopSize);
new Comment("xResultSize = " + xResultSize);
if (xStackOffsetBefore > xResultSize)
{
if (xResultSize > 0)
{
new Comment("Cleanup return");
// cleanup result values
for (int i = 0; i < xResultSize / 4; i++)
{
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
};
}
}
if (xStackOffsetBefore > 0)
{
var xExtraStack = xStackOffsetBefore - xPopSize - xResultSize;
new Comment("Cleanup extra stack");
// cleanup result values
for (int i = 0; i < xStackOffsetBefore / 4; i++)
{
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
};
}
}
}
}, nextLabel);
}
if (xMethodInfo == null
|| SizeOfType(xMethodInfo.ReturnType) == 0)
{
return;
}
}
}
}
}

View file

@ -32,10 +32,13 @@ namespace Cosmos.IL2CPU.X86.IL
// mTargetMethodInfo = GetService<IMetaDataInfoService>().GetMethodInfo(mMethod
// , mMethod, mMethodDescription, null, mCurrentMethodInfo.DebugMode);
string xNormalAddress = "";
if (aTargetMethod.IsStatic || !aTargetMethod.IsVirtual || aTargetMethod.IsFinal)
if (aTargetMethod.IsStatic
|| !aTargetMethod.IsVirtual
|| aTargetMethod.IsFinal)
{
xNormalAddress = LabelName.Get(aTargetMethod);
}
// mMethodIdentifier = GetService<IMetaDataInfoService>().GetMethodIdLabel(mMethod);
int xArgCount = aTargetMethod.GetParameters().Length;
@ -45,6 +48,7 @@ namespace Cosmos.IL2CPU.X86.IL
{
xReturnSize = Align(SizeOfType(xMethodInfo.ReturnType), 4);
}
// Extracted from MethodInformation: Calculated offset
// var xRoundedSize = ReturnSize;
//if (xRoundedSize % 4 > 0) {
@ -76,9 +80,15 @@ namespace Cosmos.IL2CPU.X86.IL
{
if (xExtraStackSize > 0)
{
new CPUx86.Sub {DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xExtraStackSize};
new CPUx86.Sub
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xExtraStackSize
};
}
new CPUx86.Call {DestinationLabel = xNormalAddress};
new CPUx86.Call
{
DestinationLabel = xNormalAddress
};
}
else
{
@ -88,10 +98,22 @@ namespace Cosmos.IL2CPU.X86.IL
* $esp + mThisOffset This
*/
new CPUx86.Mov {DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = (int)xThisOffset};
new CPUx86.Mov {DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true};
new CPUx86.Push {DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true};
new CPUx86.Push {DestinationValue = aTargetMethodUID};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = (int)xThisOffset
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true
};
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true
};
new CPUx86.Push
{
DestinationValue = aTargetMethodUID
};
new CPUx86.Call
{
DestinationLabel = LabelName.Get(VTablesImplRefs.GetMethodAddressForTypeRef)
@ -112,7 +134,10 @@ namespace Cosmos.IL2CPU.X86.IL
// mLabelName + "_AfterAddressCheck",
// true,
// xEmitCleanup );
new CPUx86.Pop {DestinationReg = CPU.RegistersEnum.ECX};
new CPUx86.Pop
{
DestinationReg = CPU.RegistersEnum.ECX
};
new Label(xCurrentMethodLabel + ".AfterAddressCheck");
if (xMethodInfo.DeclaringType == typeof(object))
@ -124,13 +149,23 @@ namespace Cosmos.IL2CPU.X86.IL
* $esp + mThisOffset This
*/
// we need to see if $this is a boxed object, and if so, we need to box it
new CPUx86.Mov {DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = (int)xThisOffset};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = (int)xThisOffset
};
//new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = ( ( uint )InstanceTypeEnum.BoxedValueType ), Size = 32 };
// EAX contains the handle now, lets dereference it
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true };
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true
};
new CPUx86.Compare {DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (int)InstanceTypeEnum.BoxedValueType, Size = 32};
new CPUx86.Compare
{
DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (int)InstanceTypeEnum.BoxedValueType, Size = 32
};
/*
* On the stack now:
@ -140,9 +175,12 @@ namespace Cosmos.IL2CPU.X86.IL
* ECX contains the method to call
* EAX contains the type pointer (not the handle!!)
*/
new CPUx86.ConditionalJump {Condition = CPUx86.ConditionalTestEnum.NotEqual, DestinationLabel = xCurrentMethodLabel + ".NotBoxedThis"};
new CPUx86.ConditionalJump
{
Condition = CPUx86.ConditionalTestEnum.NotEqual, DestinationLabel = xCurrentMethodLabel + ".NotBoxedThis"
};
/*
/*
* On the stack now:
* $esp Params
* $esp + mThisOffset This
@ -151,9 +189,15 @@ namespace Cosmos.IL2CPU.X86.IL
* EAX contains the type pointer (not the handle!!)
*/
new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = ( uint )ObjectImpl.FieldDataOffset };
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.EAX, SourceValue = (uint)ObjectImpl.FieldDataOffset
};
new CPUx86.Mov {DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)xThisOffset, SourceReg = CPUx86.Registers.EAX};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)xThisOffset, SourceReg = CPUx86.Registers.EAX
};
/*
* On the stack now:
* $esp Params
@ -165,9 +209,15 @@ namespace Cosmos.IL2CPU.X86.IL
new Label(xCurrentMethodLabel + ".NotBoxedThis");
if (xExtraStackSize > 0)
{
new CPUx86.Sub {DestinationReg = CPUx86.Registers.ESP, SourceValue = xExtraStackSize};
new CPUx86.Sub
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = xExtraStackSize
};
}
new CPUx86.Call {DestinationReg = CPUx86.Registers.ECX};
new CPUx86.Call
{
DestinationReg = CPUx86.Registers.ECX
};
new Label(xCurrentMethodLabel + ".AfterNotBoxedThis");
}
ILOp.EmitExceptionLogic(Assembler, aMethod, aOp, true,
@ -192,10 +242,14 @@ namespace Cosmos.IL2CPU.X86.IL
if (xResultSize > 0)
{
new Comment("Cleanup return");
// cleanup result values
for (int i = 0; i < xResultSize / 4; i++)
{
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
};
}
}
@ -203,10 +257,14 @@ namespace Cosmos.IL2CPU.X86.IL
{
var xExtraStack = xStackOffsetBefore - xPopSize - xResultSize;
new Comment("Cleanup extra stack");
// cleanup result values
for (int i = 0; i < xExtraStack / 4; i++)
{
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
};
}
}
}

View file

@ -10,7 +10,7 @@ using SysReflection = System.Reflection;
namespace Cosmos.IL2CPU.X86.IL
{
[Cosmos.IL2CPU.OpCode(ILOpCode.Code.Newobj)]
public class Newobj : ILOp
public class Newobj: ILOp
{
public Newobj(Cosmos.Assembler.Assembler aAsmblr)
: base(aAsmblr)
@ -26,7 +26,7 @@ namespace Cosmos.IL2CPU.X86.IL
Assemble(Assembler, aMethod, xMethod, xCurrentLabel, xType, xMethod.Value);
}
public static void Assemble(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethod, OpMethod xMethod, string currentLabel, Type objectType, MethodBase constructor)
public static void Assemble(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethod, OpMethod xMethod, string currentLabel, Type objectType, MethodBase constructor)
{
// call cctor:
if (aMethod != null)
@ -34,7 +34,10 @@ namespace Cosmos.IL2CPU.X86.IL
var xCctor = (objectType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault();
if (xCctor != null)
{
new CPUx86.Call { DestinationLabel = LabelName.Get(xCctor) };
new CPUx86.Call
{
DestinationLabel = LabelName.Get(xCctor)
};
ILOp.EmitExceptionLogic(aAssembler, aMethod, xMethod, true, null, ".AfterCCTorExceptionCheck");
new Label(".AfterCCTorExceptionCheck");
}
@ -43,6 +46,7 @@ namespace Cosmos.IL2CPU.X86.IL
if (objectType.IsValueType)
{
#region Valuetypes
new Comment("ValueType");
/*
* Current sitation on stack:
@ -67,6 +71,7 @@ namespace Cosmos.IL2CPU.X86.IL
{
throw new Exception("ValueType storage size cannot be 0.");
}
//var xStorageSize = aCtorDeclTypeInfo.StorageSize;
uint xArgSize = 0;
@ -82,28 +87,44 @@ namespace Cosmos.IL2CPU.X86.IL
new Comment("Shift: " + xShift);
if (xShift < 0)
{
new CPUx86.Sub { DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)Math.Abs(xShift) };
new CPUx86.Sub
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)Math.Abs(xShift)
};
}
else if (xShift > 0)
{
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xShift };
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xShift
};
}
// push struct ptr
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP };
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.ESP
};
// Shift args
foreach (var xParam in xParameterList)
{
uint xArgSizeForThis = Align(SizeOfType(xParam.ParameterType), 4);
for (int i = 1; i <= xArgSizeForThis / 4; i++)
{
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)xStorageSize };
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)xStorageSize
};
}
}
new Call(aAssembler).Execute(aMethod, xMethod);
// Need to put these *after* the call because the Call pops the args from the stack
// and we have mucked about on the stack, so this makes it right before the next
// op.
#endregion Valuetypes
}
else
@ -114,51 +135,113 @@ namespace Cosmos.IL2CPU.X86.IL
// array length + 8
bool xHasCalcSize = false;
// try calculating size:
if (constructor.DeclaringType == typeof(string))
{
if (xParams.Length == 1 && xParams[0].ParameterType == typeof(char[]))
if (xParams.Length == 1
&& xParams[0].ParameterType == typeof(char[]))
{
xHasCalcSize = true;
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true };
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true
};
// EAX contains a memory handle now, lets dereference it to a pointer
new CPUx86.Mov {DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true};
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true, SourceDisplacement = 8 };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EDX, SourceValue = 2 };
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.EDX };
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true, SourceDisplacement = 8
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EDX, SourceValue = 2
};
new CPUx86.Multiply
{
DestinationReg = CPUx86.Registers.EDX
};
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.EAX
};
}
else if (xParams.Length == 3 && xParams[0].ParameterType == typeof(char[]) && xParams[1].ParameterType == typeof(int) && xParams[2].ParameterType == typeof(int))
else if (xParams.Length == 3
&& xParams[0].ParameterType == typeof(char[])
&& xParams[1].ParameterType == typeof(int)
&& xParams[2].ParameterType == typeof(int))
{
xHasCalcSize = true;
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true };
new CPUx86.ShiftLeft { DestinationReg = CPUx86.Registers.EAX, SourceValue = 1 };
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true
};
new CPUx86.ShiftLeft
{
DestinationReg = CPUx86.Registers.EAX, SourceValue = 1
};
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.EAX
};
}
else if (xParams.Length == 2 && xParams[0].ParameterType == typeof(char) && xParams[1].ParameterType == typeof(int))
else if (xParams.Length == 2
&& xParams[0].ParameterType == typeof(char)
&& xParams[1].ParameterType == typeof(int))
{
xHasCalcSize = true;
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true };
new CPUx86.ShiftLeft { DestinationReg = CPUx86.Registers.EAX, SourceValue = 1 };
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true
};
new CPUx86.ShiftLeft
{
DestinationReg = CPUx86.Registers.EAX, SourceValue = 1
};
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.EAX
};
}
else
throw new NotImplementedException("In NewObj, a string ctor implementation is missing!");
}
uint xMemSize = GetStorageSize(objectType);
int xExtraSize = 12; // additional size for set values after alloc
new CPUx86.Push { DestinationValue = (uint)(xMemSize + xExtraSize) };
new CPUx86.Push
{
DestinationValue = (uint)(xMemSize + xExtraSize)
};
if (xHasCalcSize)
{
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX };
new CPUx86.Pop
{
DestinationReg = CPUx86.Registers.EAX
};
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX
};
}
// todo: probably we want to check for exceptions after calling Alloc
new CPUx86.Call { DestinationLabel = LabelName.Get(GCImplementationRefs.AllocNewObjectRef) };
new CPUx86.Call
{
DestinationLabel = LabelName.Get(GCImplementationRefs.AllocNewObjectRef)
};
new Label(".AfterAlloc");
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true };
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true
};
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true
};
// it's on the stack now 3 times. Once from the Alloc return value, twice from the pushes
@ -175,12 +258,30 @@ namespace Cosmos.IL2CPU.X86.IL
// todo: use a cleaner approach here. this class shouldnt assemble the string
string strTypeId = GetTypeIDLabel(constructor.DeclaringType);
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EBX, SourceRef = Cosmos.Assembler.ElementReference.New(strTypeId), SourceIsIndirect = true };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EBX };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32 };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32 };
new CPUx86.Pop
{
DestinationReg = CPUx86.Registers.EAX
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EBX, SourceRef = Cosmos.Assembler.ElementReference.New(strTypeId), SourceIsIndirect = true
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EBX
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32
};
new CPUx86.Mov
{
DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32
};
uint xSize = (uint)(((from item in xParams
let xQSize = Align(SizeOfType(item.ParameterType), 4)
select (int)xQSize).Take(xParams.Length).Sum()));
@ -191,16 +292,28 @@ namespace Cosmos.IL2CPU.X86.IL
new Comment(aAssembler, String.Format("Arg {0}: {1}", xParam.Name, xParamSize));
for (int i = 0; i < xParamSize; i += 4)
{
new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize + 4) };
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize + 4)
};
}
}
new CPUx86.Call { DestinationLabel = LabelName.Get(constructor) };
new CPUx86.Call
{
DestinationLabel = LabelName.Get(constructor)
};
if (aMethod != null)
{
new CPUx86.Test { DestinationReg = CPUx86.Registers.ECX, SourceValue = 2 };
new CPUx86.Test
{
DestinationReg = CPUx86.Registers.ECX, SourceValue = 2
};
string xNoErrorLabel = currentLabel + ".NoError" + LabelName.LabelCount.ToString();
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = xNoErrorLabel };
new CPUx86.ConditionalJump
{
Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = xNoErrorLabel
};
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
//{
@ -213,8 +326,13 @@ namespace Cosmos.IL2CPU.X86.IL
// };
//}
PushAlignedParameterSize(constructor);
// an exception occurred, we need to cleanup the stack, and jump to the exit
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = 4 };
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
};
//new Comment(aAssembler, "[ Newobj.Execute cleanup start count = " + aAssembler.Stack.Count.ToString() + " ]");
//foreach( var xStackInt in Assembler.Stack )
//{
@ -225,7 +343,10 @@ namespace Cosmos.IL2CPU.X86.IL
Jump_Exception(aMethod);
new Label(xNoErrorLabel);
}
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Pop
{
DestinationReg = CPUx86.Registers.EAX
};
//for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
//{
@ -239,7 +360,10 @@ namespace Cosmos.IL2CPU.X86.IL
//}
PushAlignedParameterSize(constructor);
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Push
{
DestinationReg = CPUx86.Registers.EAX
};
}
}
@ -252,7 +376,10 @@ namespace Cosmos.IL2CPU.X86.IL
for (int i = 0; i < xParams.Length; i++)
{
xSize = SizeOfType(xParams[i].ParameterType);
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = Align(xSize, 4) };
new CPUx86.Add
{
DestinationReg = CPUx86.Registers.ESP, SourceValue = Align(xSize, 4)
};
}
new Comment("[ Newobj.PushAlignedParameterSize end ]");
}