mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-10 10:11:31 +00:00
Reformat code, and add settings to editorconfig file.
This commit is contained in:
parent
870c07991a
commit
6f9fcec90a
4 changed files with 431 additions and 206 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ]");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue