This commit is contained in:
Kudzu 2017-07-31 15:15:38 -04:00
parent e19dfd6b33
commit a438fb076c
5 changed files with 106 additions and 209 deletions

View file

@ -9,5 +9,8 @@ cd source\kernel-x86
copy "00-CPU\Cosmos.CPU_Plugs\bin\Debug\netstandard1.5\Cosmos.CPU_Plugs.dll" "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Kernel\" copy "00-CPU\Cosmos.CPU_Plugs\bin\Debug\netstandard1.5\Cosmos.CPU_Plugs.dll" "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Kernel\"
copy "00-CPU\Cosmos.CPU_Asm\bin\Debug\netstandard1.5\Cosmos.CPU_Asm.dll" "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Kernel\" copy "00-CPU\Cosmos.CPU_Asm\bin\Debug\netstandard1.5\Cosmos.CPU_Asm.dll" "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Kernel\"
copy "80-System\Cosmos.System_Plugs\bin\Debug\netstandard1.5\Cosmos.System_Plugs.dll" "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Kernel\" copy "80-System\Cosmos.System_Plugs\bin\Debug\netstandard1.5\Cosmos.System_Plugs.dll" "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Kernel\"
cd ..\..
copy source\IL2CPU\bin\Debug\netcoreapp1.0 "%USERPROFILE%\AppData\Roaming\Cosmos User Kit\Build\IL2CPU"
@timeout 3 @timeout 3

View file

@ -306,6 +306,7 @@ namespace Cosmos.IL2CPU {
foreach (var xType in xAssembly.ExportedTypes) { foreach (var xType in xAssembly.ExportedTypes) {
var xTypeInfo = xType.GetTypeInfo(); var xTypeInfo = xType.GetTypeInfo();
if (!xTypeInfo.IsGenericTypeDefinition && !xTypeInfo.IsAbstract) { if (!xTypeInfo.IsGenericTypeDefinition && !xTypeInfo.IsAbstract) {
CompilerHelpers.Debug($"Checking type {xType.FullName}"); CompilerHelpers.Debug($"Checking type {xType.FullName}");

View file

@ -14,15 +14,12 @@ using Cosmos.IL2CPU.Extensions;
using Cosmos.IL2CPU.X86.IL; using Cosmos.IL2CPU.X86.IL;
using XSharp.Common; using XSharp.Common;
namespace Cosmos.IL2CPU namespace Cosmos.IL2CPU {
{ public abstract class ILOp {
public abstract class ILOp
{
public static PlugManager mPlugManager; public static PlugManager mPlugManager;
protected readonly Assembler.Assembler Assembler; protected readonly Assembler.Assembler Assembler;
protected ILOp(Assembler.Assembler aAsmblr) protected ILOp(Assembler.Assembler aAsmblr) {
{
Assembler = aAsmblr; Assembler = aAsmblr;
} }
@ -32,90 +29,72 @@ namespace Cosmos.IL2CPU
// could be used for other things, profiling, analysis, reporting, etc // could be used for other things, profiling, analysis, reporting, etc
public abstract void Execute(_MethodInfo aMethod, ILOpCode aOpCode); public abstract void Execute(_MethodInfo aMethod, ILOpCode aOpCode);
public static string GetTypeIDLabel(Type aType) public static string GetTypeIDLabel(Type aType) {
{
return "VMT__TYPE_ID_HOLDER__" + DataMember.FilterStringForIncorrectChars(LabelName.GetFullName(aType) + " ASM_IS__" + aType.GetTypeInfo().Assembly.GetName().Name); return "VMT__TYPE_ID_HOLDER__" + DataMember.FilterStringForIncorrectChars(LabelName.GetFullName(aType) + " ASM_IS__" + aType.GetTypeInfo().Assembly.GetName().Name);
} }
public static uint Align(uint aSize, uint aAlign) public static uint Align(uint aSize, uint aAlign) {
{
var xSize = aSize; var xSize = aSize;
if ((xSize % aAlign) != 0) if ((xSize % aAlign) != 0) {
{
xSize += aAlign - (xSize % aAlign); xSize += aAlign - (xSize % aAlign);
} }
return xSize; return xSize;
} }
public static int SignedAlign(int aSize, int aAlign) public static int SignedAlign(int aSize, int aAlign) {
{
int xSize = aSize; int xSize = aSize;
if ((xSize % aAlign) != 0) if ((xSize % aAlign) != 0) {
{
xSize += aAlign - (xSize % aAlign); xSize += aAlign - (xSize % aAlign);
} }
return xSize; return xSize;
} }
public static string GetLabel(_MethodInfo aMethod, ILOpCode aOpCode) public static string GetLabel(_MethodInfo aMethod, ILOpCode aOpCode) {
{
return GetLabel(aMethod, aOpCode.Position); return GetLabel(aMethod, aOpCode.Position);
} }
public static string GetLabel(MethodBase aMethod) public static string GetLabel(MethodBase aMethod) {
{
return LabelName.Get(aMethod); return LabelName.Get(aMethod);
} }
public static string GetLabel(_MethodInfo aMethod) public static string GetLabel(_MethodInfo aMethod) {
{ if (aMethod.PluggedMethod != null) {
if (aMethod.PluggedMethod != null)
{
return "PLUG_FOR___" + GetLabel(aMethod.PluggedMethod.MethodBase); return "PLUG_FOR___" + GetLabel(aMethod.PluggedMethod.MethodBase);
} }
return GetLabel(aMethod.MethodBase); return GetLabel(aMethod.MethodBase);
} }
public static string GetLabel(_MethodInfo aMethod, int aPos) public static string GetLabel(_MethodInfo aMethod, int aPos) {
{
return LabelName.Get(GetLabel(aMethod), aPos); return LabelName.Get(GetLabel(aMethod), aPos);
} }
public override string ToString() public override string ToString() {
{
return GetType().Name; return GetType().Name;
} }
protected static void Jump_Exception(_MethodInfo aMethod) protected static void Jump_Exception(_MethodInfo aMethod) {
{
// todo: port to numeric labels // todo: port to numeric labels
XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException); XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException);
} }
protected static void Jump_End(_MethodInfo aMethod) protected static void Jump_End(_MethodInfo aMethod) {
{
XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal); XS.Jump(GetLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal);
} }
public static uint GetStackCountForLocal(_MethodInfo aMethod, Type aField) public static uint GetStackCountForLocal(_MethodInfo aMethod, Type aField) {
{
var xSize = SizeOfType(aField); var xSize = SizeOfType(aField);
var xResult = xSize / 4; var xResult = xSize / 4;
if (xSize % 4 != 0) if (xSize % 4 != 0) {
{
xResult++; xResult++;
} }
return xResult; return xResult;
} }
public static uint GetEBPOffsetForLocal(_MethodInfo aMethod, int localIndex) public static uint GetEBPOffsetForLocal(_MethodInfo aMethod, int localIndex) {
{
var xLocalInfos = aMethod.MethodBase.GetLocalVariables(); var xLocalInfos = aMethod.MethodBase.GetLocalVariables();
uint xOffset = 4; uint xOffset = 4;
for (int i = 0; i < xLocalInfos.Count; i++) for (int i = 0; i < xLocalInfos.Count; i++) {
{ if (i == localIndex) {
if (i == localIndex)
{
break; break;
} }
var xField = xLocalInfos[i]; var xField = xLocalInfos[i];
@ -124,8 +103,7 @@ namespace Cosmos.IL2CPU
return xOffset; return xOffset;
} }
public static uint GetEBPOffsetForLocalForDebugger(_MethodInfo aMethod, int localIndex) public static uint GetEBPOffsetForLocalForDebugger(_MethodInfo aMethod, int localIndex) {
{
// because the memory is read in positive direction, we need to add additional size if greater than 4 // because the memory is read in positive direction, we need to add additional size if greater than 4
uint xOffset = GetEBPOffsetForLocal(aMethod, localIndex); uint xOffset = GetEBPOffsetForLocal(aMethod, localIndex);
var xLocalInfos = aMethod.MethodBase.GetLocalVariables(); var xLocalInfos = aMethod.MethodBase.GetLocalVariables();
@ -134,40 +112,32 @@ namespace Cosmos.IL2CPU
return xOffset; return xOffset;
} }
protected void ThrowNotImplementedException(string aMessage) protected void ThrowNotImplementedException(string aMessage) {
{
XS.Push(LdStr.GetContentsArrayName(aMessage)); XS.Push(LdStr.GetContentsArrayName(aMessage));
new CPU.Call new CPU.Call {
{
DestinationLabel = LabelName.Get(typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public)) DestinationLabel = LabelName.Get(typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public))
}; };
} }
protected void ThrowOverflowException() protected void ThrowOverflowException() {
{ new CPU.Call {
new CPU.Call
{
DestinationLabel = LabelName.Get(typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public)) DestinationLabel = LabelName.Get(typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public))
}; };
} }
private static void DoGetFieldsInfo(Type aType, List<_FieldInfo> aFields, bool includeStatic) private static void DoGetFieldsInfo(Type aType, List<_FieldInfo> aFields, bool includeStatic) {
{
var xCurList = new Dictionary<string, _FieldInfo>(); var xCurList = new Dictionary<string, _FieldInfo>();
var xBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; var xBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
if (includeStatic) if (includeStatic) {
{
xBindingFlags |= BindingFlags.Static; xBindingFlags |= BindingFlags.Static;
} }
var xFields = (from item in aType.GetFields(xBindingFlags) var xFields = (from item in aType.GetFields(xBindingFlags)
orderby item.Name, item.DeclaringType.ToString() orderby item.Name, item.DeclaringType.ToString()
select item).ToArray(); select item).ToArray();
for (int i = 0; i < xFields.Length; i++) for (int i = 0; i < xFields.Length; i++) {
{
var xField = xFields[i]; var xField = xFields[i];
// todo: should be possible to have GetFields only return fields from a given type, thus removing need of next statement // todo: should be possible to have GetFields only return fields from a given type, thus removing need of next statement
if (xField.DeclaringType != aType) if (xField.DeclaringType != aType) {
{
continue; continue;
} }
@ -179,8 +149,7 @@ namespace Cosmos.IL2CPU
var xFieldOffsetAttrib = var xFieldOffsetAttrib =
xField.GetCustomAttributes<FieldOffsetAttribute>(true).FirstOrDefault(); xField.GetCustomAttributes<FieldOffsetAttribute>(true).FirstOrDefault();
if (xFieldOffsetAttrib != null) if (xFieldOffsetAttrib != null) {
{
xInfo.Offset = (uint)xFieldOffsetAttrib.Value; xInfo.Offset = (uint)xFieldOffsetAttrib.Value;
} }
@ -190,25 +159,19 @@ namespace Cosmos.IL2CPU
// now check plugs // now check plugs
IDictionary<string, PlugFieldAttribute> xPlugFields; IDictionary<string, PlugFieldAttribute> xPlugFields;
if (mPlugManager.PlugFields.TryGetValue(aType, out xPlugFields)) if (mPlugManager.PlugFields.TryGetValue(aType, out xPlugFields)) {
{ foreach (var xPlugField in xPlugFields) {
foreach (var xPlugField in xPlugFields)
{
_FieldInfo xPluggedField = null; _FieldInfo xPluggedField = null;
if (xCurList.TryGetValue(xPlugField.Key, out xPluggedField)) if (xCurList.TryGetValue(xPlugField.Key, out xPluggedField)) {
{
// plugfield modifies an already existing field // plugfield modifies an already existing field
// TODO: improve. // TODO: improve.
if (xPlugField.Value.IsExternalValue) if (xPlugField.Value.IsExternalValue) {
{
xPluggedField.IsExternalValue = true; xPluggedField.IsExternalValue = true;
xPluggedField.FieldType = xPluggedField.FieldType.MakePointerType(); xPluggedField.FieldType = xPluggedField.FieldType.MakePointerType();
xPluggedField.Size = 4; xPluggedField.Size = 4;
} }
} } else {
else
{
xPluggedField = new _FieldInfo(xPlugField.Value.FieldId, SizeOfType(xPlugField.Value.FieldType), aType, xPluggedField = new _FieldInfo(xPlugField.Value.FieldId, SizeOfType(xPlugField.Value.FieldType), aType,
xPlugField.Value.FieldType); xPlugField.Value.FieldType);
aFields.Add(xPluggedField); aFields.Add(xPluggedField);
@ -217,33 +180,26 @@ namespace Cosmos.IL2CPU
} }
Type xBase = aType.GetTypeInfo().BaseType; Type xBase = aType.GetTypeInfo().BaseType;
if (xBase != null) if (xBase != null) {
{
DoGetFieldsInfo(xBase, aFields, includeStatic); DoGetFieldsInfo(xBase, aFields, includeStatic);
} }
} }
public static List<_FieldInfo> GetFieldsInfo(Type aType, bool includeStatic) public static List<_FieldInfo> GetFieldsInfo(Type aType, bool includeStatic) {
{
var xResult = new List<_FieldInfo>(16); var xResult = new List<_FieldInfo>(16);
DoGetFieldsInfo(aType, xResult, includeStatic); DoGetFieldsInfo(aType, xResult, includeStatic);
xResult.Reverse(); xResult.Reverse();
uint xOffset = 0; uint xOffset = 0;
foreach (var xInfo in xResult) foreach (var xInfo in xResult) {
{ if (!xInfo.IsOffsetSet && !xInfo.IsStatic) {
if (!xInfo.IsOffsetSet && !xInfo.IsStatic)
{
xInfo.Offset = xOffset; xInfo.Offset = xOffset;
xOffset += xInfo.Size; xOffset += xInfo.Size;
} }
} }
var xDebugInfs = new List<FIELD_INFO>(); var xDebugInfs = new List<FIELD_INFO>();
foreach (var xInfo in xResult) foreach (var xInfo in xResult) {
{ if (!xInfo.IsStatic) {
if (!xInfo.IsStatic) xDebugInfs.Add(new FIELD_INFO() {
{
xDebugInfs.Add(new FIELD_INFO()
{
TYPE = xInfo.FieldType.AssemblyQualifiedName, TYPE = xInfo.FieldType.AssemblyQualifiedName,
OFFSET = (int)xInfo.Offset, OFFSET = (int)xInfo.Offset,
NAME = GetNameForField(xInfo), NAME = GetNameForField(xInfo),
@ -257,24 +213,20 @@ namespace Cosmos.IL2CPU
return xResult; return xResult;
} }
private static void GetFieldMapping(List<_FieldInfo> aFieldInfs, List<DebugInfo.Field_Map> aFieldMapping, Type aType) private static void GetFieldMapping(List<_FieldInfo> aFieldInfs, List<DebugInfo.Field_Map> aFieldMapping, Type aType) {
{
var xFMap = new DebugInfo.Field_Map(); var xFMap = new DebugInfo.Field_Map();
xFMap.TypeName = aType.AssemblyQualifiedName; xFMap.TypeName = aType.AssemblyQualifiedName;
foreach (var xInfo in aFieldInfs) foreach (var xInfo in aFieldInfs) {
{
xFMap.FieldNames.Add(GetNameForField(xInfo)); xFMap.FieldNames.Add(GetNameForField(xInfo));
} }
aFieldMapping.Add(xFMap); aFieldMapping.Add(xFMap);
} }
private static string GetNameForField(_FieldInfo inf) private static string GetNameForField(_FieldInfo inf) {
{
// First we need to separate out the // First we need to separate out the
// actual name of field from the type of the field. // actual name of field from the type of the field.
int loc = inf.Id.IndexOf(' '); int loc = inf.Id.IndexOf(' ');
if (loc >= 0) if (loc >= 0) {
{
string fName = inf.Id.Substring(loc, inf.Id.Length - loc); string fName = inf.Id.Substring(loc, inf.Id.Length - loc);
return inf.DeclaringType.AssemblyQualifiedName + fName; return inf.DeclaringType.AssemblyQualifiedName + fName;
} }
@ -282,8 +234,7 @@ namespace Cosmos.IL2CPU
return inf.Id; return inf.Id;
} }
protected static uint GetStorageSize(Type aType) protected static uint GetStorageSize(Type aType) {
{
return (from item in GetFieldsInfo(aType, false) return (from item in GetFieldsInfo(aType, false)
where !item.IsStatic where !item.IsStatic
orderby item.Offset descending orderby item.Offset descending
@ -293,69 +244,55 @@ namespace Cosmos.IL2CPU
/// <summary> /// <summary>
/// Emits cleanup code for when an exception occurred inside a method call. /// Emits cleanup code for when an exception occurred inside a method call.
/// </summary> /// </summary>
public static void EmitExceptionCleanupAfterCall(Assembler.Assembler aAssembler, uint aReturnSize, uint aStackSizeBeforeCall, uint aTotalArgumentSizeOfMethod) public static void EmitExceptionCleanupAfterCall(Assembler.Assembler aAssembler, uint aReturnSize, uint aStackSizeBeforeCall, uint aTotalArgumentSizeOfMethod) {
{
XS.Comment("aStackSizeBeforeCall = " + aStackSizeBeforeCall); XS.Comment("aStackSizeBeforeCall = " + aStackSizeBeforeCall);
XS.Comment("aTotalArgumentSizeOfMethod = " + aTotalArgumentSizeOfMethod); XS.Comment("aTotalArgumentSizeOfMethod = " + aTotalArgumentSizeOfMethod);
XS.Comment("aReturnSize = " + aReturnSize); XS.Comment("aReturnSize = " + aReturnSize);
if (aReturnSize != 0) if (aReturnSize != 0) {
{
// at least pop return size: // at least pop return size:
XS.Comment("Cleanup return"); XS.Comment("Cleanup return");
// cleanup result values // cleanup result values
for (int i = 0; i < aReturnSize / 4; i++) for (int i = 0; i < aReturnSize / 4; i++) {
{
XS.Add(XSRegisters.ESP, 4); XS.Add(XSRegisters.ESP, 4);
} }
} }
if (aStackSizeBeforeCall > (aTotalArgumentSizeOfMethod)) if (aStackSizeBeforeCall > (aTotalArgumentSizeOfMethod)) {
{ if (aTotalArgumentSizeOfMethod > 0) {
if (aTotalArgumentSizeOfMethod > 0)
{
var xExtraStack = aStackSizeBeforeCall - aTotalArgumentSizeOfMethod; var xExtraStack = aStackSizeBeforeCall - aTotalArgumentSizeOfMethod;
XS.Comment("Cleanup extra stack"); XS.Comment("Cleanup extra stack");
// cleanup result values // cleanup result values
for (int i = 0; i < xExtraStack / 4; i++) for (int i = 0; i < xExtraStack / 4; i++) {
{
XS.Add(XSRegisters.ESP, 4); XS.Add(XSRegisters.ESP, 4);
} }
} }
} }
} }
public static void EmitExceptionLogic(Assembler.Assembler aAssembler, _MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup, string aJumpTargetNoException = null) public static void EmitExceptionLogic(Assembler.Assembler aAssembler, _MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup, string aJumpTargetNoException = null) {
{ if (aJumpTargetNoException == null) {
if (aJumpTargetNoException == null)
{
aJumpTargetNoException = GetLabel(aMethodInfo, aCurrentOpCode.NextPosition); aJumpTargetNoException = GetLabel(aMethodInfo, aCurrentOpCode.NextPosition);
} }
string xJumpTo = null; string xJumpTo = null;
if (aCurrentOpCode != null && aCurrentOpCode.CurrentExceptionRegion != null) if (aCurrentOpCode != null && aCurrentOpCode.CurrentExceptionRegion != null) {
{
// todo add support for nested handlers, see comment in Engine.cs // todo add support for nested handlers, see comment in Engine.cs
//if (!((aMethodInfo.CurrentHandler.HandlerOffset < aCurrentOpOffset) || (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset)) { //if (!((aMethodInfo.CurrentHandler.HandlerOffset < aCurrentOpOffset) || (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset)) {
XS.Comment(String.Format("CurrentOffset = {0}, HandlerStartOffset = {1}", aCurrentOpCode.Position, XS.Comment(String.Format("CurrentOffset = {0}, HandlerStartOffset = {1}", aCurrentOpCode.Position,
aCurrentOpCode.CurrentExceptionRegion.HandlerOffset)); aCurrentOpCode.CurrentExceptionRegion.HandlerOffset));
if (aCurrentOpCode.CurrentExceptionRegion.HandlerOffset > aCurrentOpCode.Position) if (aCurrentOpCode.CurrentExceptionRegion.HandlerOffset > aCurrentOpCode.Position) {
{ switch (aCurrentOpCode.CurrentExceptionRegion.Kind) {
switch (aCurrentOpCode.CurrentExceptionRegion.Kind) case ExceptionRegionKind.Catch: {
{
case ExceptionRegionKind.Catch:
{
xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset); xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset);
break; break;
} }
case ExceptionRegionKind.Finally: case ExceptionRegionKind.Finally: {
{
xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset); xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionRegion.HandlerOffset);
break; break;
} }
default: default: {
{
throw new Exception("ExceptionHandlerType '" + aCurrentOpCode.CurrentExceptionRegion.Kind.ToString() + throw new Exception("ExceptionHandlerType '" + aCurrentOpCode.CurrentExceptionRegion.Kind.ToString() +
"' not supported yet!"); "' not supported yet!");
} }
@ -363,44 +300,29 @@ namespace Cosmos.IL2CPU
} }
} }
// if aDoTest is true, we check ECX for exception flags // if aDoTest is true, we check ECX for exception flags
if (!aDoTest) if (!aDoTest) {
{
//new CPU.Call("_CODE_REQUESTED_BREAK_"); //new CPU.Call("_CODE_REQUESTED_BREAK_");
if (xJumpTo == null) if (xJumpTo == null) {
{
Jump_Exception(aMethodInfo); Jump_Exception(aMethodInfo);
} } else {
else
{
XS.Jump(xJumpTo); XS.Jump(xJumpTo);
} }
} } else {
else
{
XS.Test(XSRegisters.ECX, 2); XS.Test(XSRegisters.ECX, 2);
if (aCleanup != null) if (aCleanup != null) {
{
XS.Jump(CPU.ConditionalTestEnum.Equal, aJumpTargetNoException); XS.Jump(CPU.ConditionalTestEnum.Equal, aJumpTargetNoException);
aCleanup(); aCleanup();
if (xJumpTo == null) if (xJumpTo == null) {
{
XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException); XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException);
} } else {
else
{
XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo); XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo);
} }
} } else {
else if (xJumpTo == null) {
{
if (xJumpTo == null)
{
XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException); XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException);
} } else {
else
{
XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo); XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo);
} }
} }
@ -408,16 +330,12 @@ namespace Cosmos.IL2CPU
} }
protected static void DoNullReferenceCheck(Assembler.Assembler assembler, bool debugEnabled, int stackOffsetToCheck) protected static void DoNullReferenceCheck(Assembler.Assembler assembler, bool debugEnabled, int stackOffsetToCheck) {
{ if (stackOffsetToCheck != SignedAlign(stackOffsetToCheck, 4)) {
if (stackOffsetToCheck != SignedAlign(stackOffsetToCheck, 4))
{
throw new Exception("Stack offset not aligned!"); throw new Exception("Stack offset not aligned!");
} }
if (debugEnabled) if (debugEnabled) {
{ //if (!CompilerEngine.UseGen3Kernel) {
if (!CompilerEngine.UseGen3Kernel)
{
XS.Compare(XSRegisters.ESP, 0, destinationDisplacement: (int)stackOffsetToCheck); XS.Compare(XSRegisters.ESP, 0, destinationDisplacement: (int)stackOffsetToCheck);
XS.Jump(CPU.ConditionalTestEnum.NotEqual, ".AfterNullCheck"); XS.Jump(CPU.ConditionalTestEnum.NotEqual, ".AfterNullCheck");
XS.ClearInterruptFlag(); XS.ClearInterruptFlag();
@ -425,31 +343,27 @@ namespace Cosmos.IL2CPU
XS.Call(".NullCheck_GetCurrAddress"); XS.Call(".NullCheck_GetCurrAddress");
XS.Label(".NullCheck_GetCurrAddress"); XS.Label(".NullCheck_GetCurrAddress");
XS.Pop(XSRegisters.EAX); XS.Pop(XSRegisters.EAX);
new CPU.Mov new CPU.Mov {
{
DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationRef = ElementReference.New("DebugStub_CallerEIP"),
DestinationIsIndirect = true, DestinationIsIndirect = true,
SourceReg = CPU.RegistersEnum.EAX SourceReg = CPU.RegistersEnum.EAX
}; };
XS.Call("DebugStub_SendNullReferenceOccurred"); XS.Call("DebugStub_SendNullReferenceOccurred");
} //}
XS.Halt(); XS.Halt();
XS.Label(".AfterNullCheck"); XS.Label(".AfterNullCheck");
} }
} }
public static _FieldInfo ResolveField(Type aDeclaringType, string aField, bool aOnlyInstance) public static _FieldInfo ResolveField(Type aDeclaringType, string aField, bool aOnlyInstance) {
{
var xFields = GetFieldsInfo(aDeclaringType, !aOnlyInstance); var xFields = GetFieldsInfo(aDeclaringType, !aOnlyInstance);
var xFieldInfo = (from item in xFields var xFieldInfo = (from item in xFields
where item.Id == aField where item.Id == aField
&& (!aOnlyInstance || item.IsStatic == false) && (!aOnlyInstance || item.IsStatic == false)
select item).SingleOrDefault(); select item).SingleOrDefault();
if (xFieldInfo == null) if (xFieldInfo == null) {
{
Console.WriteLine("Following fields have been found on '{0}'", aDeclaringType.FullName); Console.WriteLine("Following fields have been found on '{0}'", aDeclaringType.FullName);
foreach (var xField in xFields) foreach (var xField in xFields) {
{
Console.WriteLine("\t'{0}'", xField.Id); Console.WriteLine("\t'{0}'", xField.Id);
} }
throw new Exception(string.Format("Field '{0}' not found on type '{1}'", aField, aDeclaringType.FullName)); throw new Exception(string.Format("Field '{0}' not found on type '{1}'", aField, aDeclaringType.FullName));
@ -457,15 +371,12 @@ namespace Cosmos.IL2CPU
return xFieldInfo; return xFieldInfo;
} }
protected static void CopyValue(XSRegisters.Register32 destination, int destinationDisplacement, XSRegisters.Register32 source, int sourceDisplacement, uint size) protected static void CopyValue(XSRegisters.Register32 destination, int destinationDisplacement, XSRegisters.Register32 source, int sourceDisplacement, uint size) {
{ for (int i = 0; i < (size / 4); i++) {
for (int i = 0; i < (size / 4); i++)
{
XS.Set(XSRegisters.EAX, source, sourceDisplacement: sourceDisplacement + (i * 4)); XS.Set(XSRegisters.EAX, source, sourceDisplacement: sourceDisplacement + (i * 4));
XS.Set(destination, XSRegisters.EAX, destinationDisplacement: destinationDisplacement + (i * 4)); XS.Set(destination, XSRegisters.EAX, destinationDisplacement: destinationDisplacement + (i * 4));
} }
switch (size % 4) switch (size % 4) {
{
case 1: case 1:
XS.Set(XSRegisters.AL, source, sourceDisplacement: (int)(sourceDisplacement + ((size / 4) * 4))); XS.Set(XSRegisters.AL, source, sourceDisplacement: (int)(sourceDisplacement + ((size / 4) * 4)));
XS.Set(destination, XSRegisters.AL, destinationDisplacement: (int)(destinationDisplacement + ((size / 4) * 4))); XS.Set(destination, XSRegisters.AL, destinationDisplacement: (int)(destinationDisplacement + ((size / 4) * 4)));
@ -482,64 +393,51 @@ namespace Cosmos.IL2CPU
} }
// Compat shim // Compat shim
public static bool TypeIsReferenceType(Type aType) public static bool TypeIsReferenceType(Type aType) {
{
return TypeIsReferenceType(aType.GetTypeInfo()); return TypeIsReferenceType(aType.GetTypeInfo());
} }
private static bool TypeIsReferenceType(TypeInfo aType) private static bool TypeIsReferenceType(TypeInfo aType) {
{
return !aType.IsValueType && !aType.IsPointer && !aType.IsByRef; return !aType.IsValueType && !aType.IsPointer && !aType.IsByRef;
} }
public static bool IsIntegerSigned(Type aType) public static bool IsIntegerSigned(Type aType) {
{
return aType.FullName == "System.SByte" || aType.FullName == "System.Int16" || aType.FullName == "System.Int32" || aType.FullName == "System.Int64"; return aType.FullName == "System.SByte" || aType.FullName == "System.Int16" || aType.FullName == "System.Int32" || aType.FullName == "System.Int64";
} }
public static bool IsIntegralType(Type type) public static bool IsIntegralType(Type type) {
{
return type == typeof(byte) || type == typeof(sbyte) || type == typeof(ushort) || type == typeof(short) return type == typeof(byte) || type == typeof(sbyte) || type == typeof(ushort) || type == typeof(short)
|| type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) || type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong)
|| type == typeof(char) || type == typeof(IntPtr) || type == typeof(UIntPtr); || type == typeof(char) || type == typeof(IntPtr) || type == typeof(UIntPtr);
} }
public static bool IsIntegralTypeOrPointer(Type type) public static bool IsIntegralTypeOrPointer(Type type) {
{
return IsIntegralType(type) || type.IsPointer || type.IsByRef; return IsIntegralType(type) || type.IsPointer || type.IsByRef;
} }
public static bool IsPointer(Type aPointer) public static bool IsPointer(Type aPointer) {
{
return aPointer.IsPointer || aPointer.IsByRef || aPointer == typeof(IntPtr) || aPointer == typeof(UIntPtr); return aPointer.IsPointer || aPointer.IsByRef || aPointer == typeof(IntPtr) || aPointer == typeof(UIntPtr);
} }
// Compat shim. // Compat shim.
public static uint SizeOfType(Type aType) public static uint SizeOfType(Type aType) {
{
return SizeOfType(aType.GetTypeInfo()); return SizeOfType(aType.GetTypeInfo());
} }
private static uint SizeOfType(TypeInfo aType) private static uint SizeOfType(TypeInfo aType) {
{ if (aType == null) {
if (aType == null)
{
throw new ArgumentNullException("aType"); throw new ArgumentNullException("aType");
} }
if (aType.IsPointer || aType.IsByRef) if (aType.IsPointer || aType.IsByRef) {
{
return 4; return 4;
} }
if (aType.FullName == "System.Void") if (aType.FullName == "System.Void") {
{
return 0; return 0;
} }
if (TypeIsReferenceType(aType)) if (TypeIsReferenceType(aType)) {
{
return 8; return 8;
} }
switch (aType.FullName) switch (aType.FullName) {
{
case "System.Char": case "System.Char":
return 2; return 2;
case "System.Byte": case "System.Byte":
@ -573,8 +471,7 @@ namespace Cosmos.IL2CPU
case "System.DateTime": case "System.DateTime":
return 8; return 8;
} }
if (aType.FullName != null && aType.FullName.EndsWith("*")) if (aType.FullName != null && aType.FullName.EndsWith("*")) {
{
// pointer // pointer
return 4; return 4;
} }
@ -583,15 +480,12 @@ namespace Cosmos.IL2CPU
//if (xTypeSpec != null) { //if (xTypeSpec != null) {
// return 4; // return 4;
//} //}
if (aType.IsEnum) if (aType.IsEnum) {
{
return SizeOfType(aType.GetField("value__").FieldType); return SizeOfType(aType.GetField("value__").FieldType);
} }
if (aType.IsValueType) if (aType.IsValueType) {
{
var xSla = aType.StructLayoutAttribute; var xSla = aType.StructLayoutAttribute;
if ((xSla != null) && (xSla.Size > 0)) if ((xSla != null) && (xSla.Size > 0)) {
{
return (uint)xSla.Size; return (uint)xSla.Size;
} }
return (uint)(from item in GetFieldsInfo(aType.AsType(), false) return (uint)(from item in GetFieldsInfo(aType.AsType(), false)
@ -600,8 +494,7 @@ namespace Cosmos.IL2CPU
return 4; return 4;
} }
protected static bool TypeIsFloat(Type type) protected static bool TypeIsFloat(Type type) {
{
return type == typeof(float) || type == typeof(double); return type == typeof(float) || type == typeof(double);
} }
} }