This commit is contained in:
mterwoord_cp 2014-07-18 16:48:16 +00:00
parent 0bb7fb87e5
commit c4de249bee
7 changed files with 285 additions and 74 deletions

View file

@ -17,7 +17,7 @@ namespace DebugCompiler
internal class Program
{
//public const string CosmosRoot = @"e:\Cosmos";
public const string CosmosRoot = @"c:\data\sources\cosmos";
public const string CosmosRoot = @"e:\OpenSOurce\Cosmos";
//public const string CosmosRoot = @"C:\Users\Huge\Documents\Visual Studio 2010\Projects\IL2CPU";
private const string KernelFile = CosmosRoot + @"\Users\Kudzu\Breakpoints\bin\Debug\Playground.Kudzu.BreakpointsKernel.dll";
@ -50,7 +50,7 @@ namespace DebugCompiler
xTask.OnLogException = (m) =>
{
Console.WriteLine("Exception: {0}", m.ToString());
Console.ReadLine();
//Console.ReadLine();
};
if (xTask.Execute())
{
@ -66,7 +66,7 @@ namespace DebugCompiler
catch (Exception E)
{
Console.WriteLine(E.ToString());
Console.ReadLine();
//Console.ReadLine();
return;
}
Console.WriteLine("Run took {0}", xSW.Elapsed);

View file

@ -375,5 +375,19 @@ namespace Cosmos.IL2CPU {
xNextOpCode.InterpretStackTypes(aOpCodes, aStack, ref aSituationChanged, aMaxRecursionDepth - 1);
}
}
protected bool IsIntegralType(Type type)
{
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(char);
}
}
}

View file

@ -141,11 +141,7 @@ namespace Cosmos.IL2CPU.ILOpCodes {
{
return;
}
if (xValue1 == typeof (int) && xValue2 == typeof (int))
{
return;
}
if (xValue1 == typeof(long) && xValue2 == typeof(long))
if (IsIntegralType(xValue1) && IsIntegralType(xValue2))
{
return;
}
@ -172,6 +168,12 @@ namespace Cosmos.IL2CPU.ILOpCodes {
{
return;
}
if (xValue1.IsClass &&
xValue2.IsClass)
{
return;
}
throw new Exception(String.Format("Comparing types '{0}' and '{1}' not supported!", xValue1.AssemblyQualifiedName, xValue2.AssemblyQualifiedName));
default:
throw new NotImplementedException("Checks for opcode " + OpCode + " not implemented!");
@ -194,13 +196,13 @@ namespace Cosmos.IL2CPU.ILOpCodes {
case Code.Bge_Un:
case Code.Beq:
case Code.Bne_Un:
case Code.Br:
base.DoInterpretNextInstructionStackTypes(aOpCodes, new Stack<Type>(aStack), ref aSituationChanged, aMaxRecursionDepth);
if (Value > Position)
{
InterpretInstruction(Value, aOpCodes, aStack, ref aSituationChanged, aMaxRecursionDepth);
}
break;
case Code.Br:
case Code.Leave:
if (Value > Position)
{

View file

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Cosmos.IL2CPU.X86.IL;
using FieldInfo = System.Reflection.FieldInfo;
namespace Cosmos.IL2CPU.ILOpCodes {
public class OpField : ILOpCode {
@ -55,34 +57,13 @@ namespace Cosmos.IL2CPU.ILOpCodes {
base.DoInitStackAnalysis(aMethod);
switch (OpCode)
{
case Code.Stsfld:
StackPopTypes[0] = Value.FieldType;
if (StackPopTypes[0].IsEnum)
{
StackPopTypes[0] = StackPopTypes[0].GetEnumUnderlyingType();
}
return;
case Code.Ldsfld:
{ case Code.Ldsfld:
StackPushTypes[0] = Value.FieldType;
if (StackPushTypes[0].IsEnum)
{
StackPushTypes[0] = StackPushTypes[0].GetEnumUnderlyingType();
}
return;
case Code.Stfld:
//StackPopTypes[0] = Value.FieldType;
//if (StackPopTypes[0].IsEnum)
//{
// StackPopTypes[0] = StackPopTypes[0].GetEnumUnderlyingType();
//}
//else if (Value.DeclaringType.IsValueType)
//{
// StackPopTypes[0] = typeof(void*);
//}
//StackPopTypes[1] = Value.DeclaringType;
return;
case Code.Ldfld:
StackPushTypes[0] = Value.FieldType;
@ -135,6 +116,10 @@ namespace Cosmos.IL2CPU.ILOpCodes {
{
return;
}
if (IsIntegralType(expectedType) && IsIntegralType(StackPopTypes[0]))
{
return;
}
if (expectedType == typeof (bool))
{
if (StackPopTypes[0] == typeof (int))
@ -142,7 +127,53 @@ namespace Cosmos.IL2CPU.ILOpCodes {
return;
}
}
throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ")");
if (StackPopTypes[0] == typeof(NullRef))
{
return;
}
if (expectedType.IsAssignableFrom(StackPopTypes[0]))
{
return;
}
throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + expectedType.FullName + ")");
case Code.Stsfld:
if (StackPopTypes[0] == null)
{
return;
}
expectedType = Value.FieldType;
if (expectedType.IsEnum)
{
expectedType = expectedType.GetEnumUnderlyingType();
}
else if (Value.DeclaringType.IsValueType)
{
expectedType = typeof(void*);
}
if (StackPopTypes[0] == expectedType || StackPopTypes[0] == Value.FieldType)
{
return;
}
if (IsIntegralType(expectedType) && IsIntegralType(StackPopTypes[0]))
{
return;
}
if (expectedType == typeof(bool))
{
if (StackPopTypes[0] == typeof(int))
{
return;
}
}
if (expectedType.IsAssignableFrom(StackPopTypes[0]))
{
return;
}
if (StackPopTypes[0] == typeof(NullRef))
{
return;
}
throw new Exception("Wrong Poptype encountered! (Type = " + StackPopTypes[0].FullName + ", expected = " + expectedType.FullName + ")");
}
}
}

View file

@ -138,7 +138,7 @@ namespace Cosmos.IL2CPU.ILOpCodes {
case Code.Dup:
return 1;
case Code.Volatile:
return 1;
return 0;
case Code.Endfinally:
return 0;
default:
@ -264,7 +264,7 @@ namespace Cosmos.IL2CPU.ILOpCodes {
case Code.Dup:
return 2;
case Code.Volatile:
return 1;
return 0;
case Code.Endfinally:
return 0;
default:
@ -283,26 +283,6 @@ namespace Cosmos.IL2CPU.ILOpCodes {
StackPopTypes[1] = typeof(void*);
return;
case Code.Stind_I1:
StackPopTypes[0] = typeof (sbyte);
StackPopTypes[1] = typeof(void*);
return;
case Code.Stind_I2:
StackPopTypes[0] = typeof (short);
StackPopTypes[1] = typeof(void*);
return;
case Code.Stind_I4:
StackPopTypes[0] = typeof (int);
StackPopTypes[1] = typeof(void*);
return;
case Code.Stind_I8:
StackPopTypes[0] = typeof (long);
StackPopTypes[1] = typeof(void*);
return;
case Code.Ldind_U1:
StackPushTypes[0] = typeof (byte);
return;
@ -557,6 +537,13 @@ namespace Cosmos.IL2CPU.ILOpCodes {
aSituationChanged = true;
return;
}
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(IntPtr))
|| (StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(int)))
{
StackPushTypes[0] = typeof(IntPtr);
aSituationChanged = true;
return;
}
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(uint))
|| (StackPopTypes[0] == typeof(uint) && StackPopTypes[1] == typeof(int)))
{
@ -585,6 +572,13 @@ namespace Cosmos.IL2CPU.ILOpCodes {
aSituationChanged = true;
return;
}
if ((StackPopTypes[0] == typeof(int) && StackPopTypes[1] == typeof(char))
|| (StackPopTypes[0] == typeof(char) && StackPopTypes[1] == typeof(int)))
{
StackPushTypes[0] = typeof(int);
aSituationChanged = true;
return;
}
if (StackPopTypes[0] == typeof(IntPtr) && StackPopTypes[1] == typeof(IntPtr))
{
StackPushTypes[0] = typeof(uint);
@ -609,6 +603,12 @@ namespace Cosmos.IL2CPU.ILOpCodes {
aSituationChanged = true;
return;
}
if (StackPopTypes[0] == typeof(ulong) && StackPopTypes[1] == typeof(ulong))
{
StackPushTypes[0] = typeof(ulong);
aSituationChanged = true;
return;
}
if (StackPopTypes[0] == typeof(Double) && StackPopTypes[1] == typeof(Double))
{
StackPushTypes[0] = typeof(Double);
@ -621,8 +621,23 @@ namespace Cosmos.IL2CPU.ILOpCodes {
aSituationChanged = true;
return;
}
throw new NotImplementedException(string.Format("Add on types '{0}' and '{1}' not yet implemented!", StackPopTypes[0], StackPopTypes[1]));
if (OpCode == Code.Add &&
((StackPopTypes[0] == typeof(IntPtr) && (StackPopTypes[1].IsPointer || StackPopTypes[1].IsByRef))
|| ((StackPopTypes[0].IsPointer || StackPopTypes[0].IsByRef) && StackPopTypes[1] == typeof(IntPtr))))
{
if (StackPopTypes[0] == typeof(IntPtr))
{
StackPushTypes[0] = StackPopTypes[1];
}
else
{
StackPushTypes[0] = StackPopTypes[0];
}
aSituationChanged = true;
return;
}
throw new NotImplementedException(string.Format("{0} on types '{1}' and '{2}' not yet implemented!", OpCode, StackPopTypes[0], StackPopTypes[1]));
}
break;
case Code.Stelem_I2:
@ -680,6 +695,18 @@ namespace Cosmos.IL2CPU.ILOpCodes {
aSituationChanged = true;
return;
}
if (xTypeValue == typeof(ushort) && xTypeShift == typeof(int))
{
StackPushTypes[0] = typeof(int);
aSituationChanged = true;
return;
}
if (xTypeValue == typeof(char) && xTypeShift == typeof(int))
{
StackPushTypes[0] = typeof(int);
aSituationChanged = true;
return;
}
if (xTypeValue == typeof(uint) && xTypeShift == typeof(int))
{
StackPushTypes[0] = typeof(int);
@ -741,7 +768,91 @@ namespace Cosmos.IL2CPU.ILOpCodes {
return;
}
return;
case Code.Stind_I1:
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
{
return;
}
if (StackPopTypes[0] != typeof(sbyte) &&
StackPopTypes[0] != typeof(byte))
{
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
}
if (!IsPointer(StackPopTypes[1]))
{
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
}
break;
case Code.Stind_I2:
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
{
return;
}
if (StackPopTypes[0] != typeof(short) &&
StackPopTypes[0] != typeof(ushort) &&
StackPopTypes[0] != typeof(int) &&
StackPopTypes[0] != typeof(uint) &&
StackPopTypes[0] != typeof(char))
{
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
}
if (!IsPointer(StackPopTypes[1]))
{
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
}
break;
case Code.Stind_I4:
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
{
return;
}
if (StackPopTypes[0] != typeof(int) &&
StackPopTypes[0] != typeof(uint))
{
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
}
if (!IsPointer(StackPopTypes[1]))
{
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
}
break;
case Code.Stind_I8:
if (StackPopTypes[1] == null || StackPopTypes[0] == null)
{
return;
}
if (StackPopTypes[0] != typeof(long) &&
StackPopTypes[0] != typeof(ulong))
{
throw new Exception("Wrong value type: " + StackPopTypes[0].FullName);
}
if (!IsPointer(StackPopTypes[1]))
{
throw new Exception("Wrong Pointer type: " + StackPopTypes[1].FullName);
}
break;
case Code.Ldind_Ref:
if (StackPushTypes[0] != null)
{
return;
}
if (StackPopTypes[0] == null)
{
return;
}
if (!StackPopTypes[0].IsByRef)
{
throw new Exception("Invalid ref type: " + StackPopTypes[0].FullName);
}
StackPushTypes[0] = StackPopTypes[0].GetElementType();
aSituationChanged = true;
break;
}
}
private bool IsPointer(Type aPointer)
{
return aPointer.IsPointer || aPointer.IsByRef || aPointer == typeof(IntPtr) || aPointer == typeof(UIntPtr);
}
}
}

View file

@ -42,11 +42,41 @@ namespace Cosmos.IL2CPU.ILOpCodes {
switch (OpCode)
{
case Code.Switch:
StackPopTypes[0] = typeof(uint);
//StackPopTypes[0] = typeof(uint);
break;
default:
break;
}
}
/// <summary>
/// Based on updated StackPopTypes, try to update
/// </summary>
protected override void DoInterpretStackTypes(ref bool aSituationChanged)
{
base.DoInterpretStackTypes(ref aSituationChanged);
// no switch necessary, there's only 1 instruction using this type.
if (StackPopTypes[0] == null)
{
return;
}
if (StackPopTypes[0] == typeof(int) ||
StackPopTypes[0] == typeof(byte))
{
return;
}
throw new Exception("Wrong type: " + StackPopTypes[0].FullName);
}
protected override void DoInterpretNextInstructionStackTypes(IDictionary<int, ILOpCode> aOpCodes, Stack<Type> aStack, ref bool aSituationChanged, int aMaxRecursionDepth)
{
base.DoInterpretNextInstructionStackTypes(aOpCodes, new Stack<Type>(aStack), ref aSituationChanged, aMaxRecursionDepth);
foreach (var xTarget in BranchLocations)
{
base.InterpretInstruction(xTarget, aOpCodes, new Stack<Type>(aStack), ref aSituationChanged, aMaxRecursionDepth);
}
}
}
}

View file

@ -5,11 +5,13 @@ using System.Reflection;
using System.Text;
namespace Cosmos.IL2CPU.ILOpCodes {
public class OpType : ILOpCode {
public class OpType: ILOpCode
{
public readonly Type Value;
public OpType(Code aOpCode, int aPos, int aNextPos, Type aValue, System.Reflection.ExceptionHandlingClause aCurrentExceptionHandler)
: base(aOpCode, aPos, aNextPos, aCurrentExceptionHandler) {
: base(aOpCode, aPos, aNextPos, aCurrentExceptionHandler)
{
Value = aValue;
}
@ -81,10 +83,9 @@ namespace Cosmos.IL2CPU.ILOpCodes {
StackPushTypes[0] = typeof(void*);
return;
case Code.Box:
StackPopTypes[0] = Value;
if (Value.IsPrimitive)
{
StackPushTypes[0] = typeof (Box<>).MakeGenericType(Value);
StackPushTypes[0] = typeof(Box<>).MakeGenericType(Value);
}
else
{
@ -103,21 +104,12 @@ namespace Cosmos.IL2CPU.ILOpCodes {
StackPushTypes[0] = Value;
return;
case Code.Isinst:
if (Value.IsGenericType && Value.GetGenericTypeDefinition() == typeof(Nullable<>))
{
StackPopTypes[0] = typeof(Box<>).MakeGenericType(Value.GetGenericArguments()[0]);
}
else if (Value.IsValueType)
{
StackPopTypes[0] = typeof(Box<>).MakeGenericType(Value);
}
else
{
StackPopTypes[0] = Value;
}
StackPopTypes[0] = typeof(object);
StackPushTypes[0] = typeof(bool);
return;
case Code.Castclass:
if (Value.IsGenericType && Value.GetGenericTypeDefinition() == typeof(Nullable<>))
if (Value.IsGenericType &&
Value.GetGenericTypeDefinition() == typeof(Nullable<>))
{
StackPushTypes[0] = typeof(Box<>).MakeGenericType(Value.GetGenericArguments()[0]);
}
@ -134,5 +126,36 @@ namespace Cosmos.IL2CPU.ILOpCodes {
break;
}
}
/// <summary>
/// Based on updated StackPopTypes, try to update
/// </summary>
protected override void DoInterpretStackTypes(ref bool aSituationChanged)
{
base.DoInterpretStackTypes(ref aSituationChanged);
switch (OpCode)
{
case Code.Box:
if (StackPushTypes[0] != null)
{
return;
}
if (StackPopTypes[0] == null)
{
return;
}
if (IsIntegralType(StackPopTypes[0]) &&
IsIntegralType(Value))
{
StackPushTypes[0] = typeof(Box<>).MakeGenericType(Value);
aSituationChanged = true;
return;
}
throw new Exception("Wrong poptype: " + StackPopTypes[0].FullName);
}
}
}
}