Fixed exceptions

This commit is contained in:
mterwoord_cp 2008-02-27 18:17:59 +00:00
parent 1a9805a18a
commit edac084b3d
26 changed files with 2175 additions and 112 deletions

View file

@ -54,7 +54,6 @@ namespace Indy.IL2CPU.Assembler {
}
public static void ExceptionOccurred() {
Console.WriteLine("Exception Occurred!");
System.Diagnostics.Debugger.Break();
}

View file

@ -22,20 +22,20 @@ namespace Indy.IL2CPU.IL.X86 {
//} else {
mTheSize = Engine.GetFieldStorageSize(xTypeRef);
//}
if (((mTheSize / 4) * 4) != mTheSize) {
throw new Exception("Incorrect Datasize. ( ((mTheSize / 4) * 4) === mTheSize should evaluate to true!");
}
//if (((mTheSize / 4) * 4) != mTheSize) {
// throw new Exception("Incorrect Datasize. ( ((mTheSize / 4) * 4) === mTheSize should evaluate to true!");
//}
//if (!(xTypeRef is GenericParameter)) {
mTypeId = Engine.RegisterType(xTypeRef);
//}
}
public override void DoAssemble() {
new CPUx86.Pushd("0x" + (4 + ObjectImpl.FieldDataOffset).ToString("X").ToUpper());
new CPUx86.Pushd("0x" + (ObjectImpl.FieldDataOffset + mTheSize + (4 - (mTheSize % 4))).ToString("X").ToUpper());
new CPUx86.Call(CPU.Label.GenerateLabelName(RuntimeEngineRefs.Heap_AllocNewObjectRef));
new CPUx86.Move("dword", CPUx86.Registers.AtEAX, "0x" + mTypeId.ToString("X"));
new CPUx86.Move("dword", "[eax + 4]", "0x" + InstanceTypeEnum.BoxedValueType.ToString("X"));
for (int i = 0; i < (mTheSize / 4); i++) {
for (int i = 0; i < ((mTheSize + (4 - (mTheSize % 4))) / 4); i++) {
new CPUx86.Pop(CPUx86.Registers.EDX);
new CPUx86.Move("dword", "[eax + 0x" + (ObjectImpl.FieldDataOffset + (i * 4)).ToString("X") + "]", "edx");
}

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using CPU = Indy.IL2CPU.Assembler;
using CPUx86 = Indy.IL2CPU.Assembler.X86;
using System.Reflection;
@ -20,17 +19,21 @@ namespace Indy.IL2CPU.IL.X86 {
private MethodInformation mMethodInfo;
private MethodInformation mTargetMethodInfo;
private string mNextLabelName;
public Call(MethodBase aMethod)
private int mCurrentILOffset;
public Call(MethodBase aMethod, int aCurrentILOffset)
: base(null, null) {
if (aMethod == null) {
throw new ArgumentNullException("aMethod");
}
Initialize(aMethod);
Initialize(aMethod, aCurrentILOffset);
}
public static void EmitExceptionLogic(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aNextLabel, bool aDoTest) {
public static void EmitExceptionLogic(Assembler.Assembler aAssembler, int aCurrentOpOffset, MethodInformation aMethodInfo, string aNextLabel, bool aDoTest) {
string xJumpTo = MethodFooterOp.EndOfMethodLabelNameException;
if (aMethodInfo != null && aMethodInfo.CurrentHandler != null) {
if (aMethodInfo.CurrentHandler.HandlerOffset >= aCurrentOpOffset && (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset) {
return;
}
switch (aMethodInfo.CurrentHandler.Flags) {
case ExceptionHandlingClauseOptions.Clause: {
xJumpTo = Op.GetInstructionLabel(aMethodInfo.CurrentHandler.HandlerOffset);
@ -52,20 +55,15 @@ namespace Indy.IL2CPU.IL.X86 {
new CPUx86.Test("ecx", "2");
new CPUx86.JumpIfNotEquals(xJumpTo);
}
// }
// new CPUx86.JumpAlways(xJumpTo);
//}
}
private void Initialize(MethodBase aMethod) {
private void Initialize(MethodBase aMethod, int aCurrentILOffset) {
mIsDebugger_Break = aMethod.GetFullName() == "System.Void System.Diagnostics.Debugger.Break()";
if (mIsDebugger_Break) {
return;
}
mCurrentILOffset = aCurrentILOffset;
mTargetMethodInfo = Engine.GetMethodInfo(aMethod, aMethod, Label.GenerateLabelName(aMethod), Engine.GetTypeInfo(aMethod.DeclaringType));
mResultSize = 0;
if (mTargetMethodInfo != null) {
mResultSize = mTargetMethodInfo.ReturnSize;
@ -102,13 +100,13 @@ namespace Indy.IL2CPU.IL.X86 {
MethodBase xMethod = aReader.OperandValueMethod;
mMethodInfo = aMethodInfo;
if (!aReader.EndOfStream) {
mNextLabelName = GetInstructionLabel(aReader.Position);
mNextLabelName = GetInstructionLabel(aReader.NextPosition);
}
Initialize(xMethod);
Initialize(xMethod, (int)aReader.Position);
}
public void Assemble(string aMethod, int aArgumentCount) {
new CPUx86.Call(aMethod);
EmitExceptionLogic(Assembler, mMethodInfo, mNextLabelName, true);
EmitExceptionLogic(Assembler, mCurrentILOffset, mMethodInfo, mNextLabelName, true);
for (int i = 0; i < aArgumentCount; i++) {
Assembler.StackContents.Pop();
}

View file

@ -19,6 +19,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string mLabelName;
private readonly MethodInformation mCurrentMethodInfo;
private readonly MethodInformation mTargetMethodInfo;
private readonly int mCurrentILOffset;
public Callvirt(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
mLabelName = GetInstructionLabel(aReader);
@ -43,6 +44,7 @@ namespace Indy.IL2CPU.IL.X86 {
mArgumentCount = mTargetMethodInfo.Arguments.Length;
mReturnSize = mTargetMethodInfo.ReturnSize;
mThisOffset = mTargetMethodInfo.Arguments[0].Offset;
mCurrentILOffset = aReader.Position;
}
public override void DoAssemble() {
@ -59,13 +61,13 @@ namespace Indy.IL2CPU.IL.X86 {
}
//Assembler.Add(new CPUx86.Pop("eax"));
//Assembler.Add(new CPUx86.Pushd("eax"));
EmitCompareWithNull(Assembler, mCurrentMethodInfo, "[esp + 0x" + mThisOffset.ToString("X") + "]", mLabelName, mLabelName + "_AfterNullRefCheck", xEmitCleanup);
EmitCompareWithNull(Assembler, mCurrentMethodInfo, "[esp + 0x" + mThisOffset.ToString("X") + "]", mLabelName, mLabelName + "_AfterNullRefCheck", xEmitCleanup, mCurrentILOffset);
new CPU.Label(mLabelName + "_AfterNullRefCheck");
new CPUx86.Move(CPUx86.Registers.EAX, "[esp + 0x" + mThisOffset.ToString("X") + "]");
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
new CPUx86.Pushd("0" + mMethodIdentifier.ToString("X") + "h");
new CPUx86.Call(CPU.Label.GenerateLabelName(VTablesImplRefs.GetMethodAddressForTypeRef));
Call.EmitExceptionLogic(Assembler, mCurrentMethodInfo, mLabelName + "_AfterAddressCheck", true);
Call.EmitExceptionLogic(Assembler, mCurrentILOffset, mCurrentMethodInfo, mLabelName + "_AfterAddressCheck", true);
new CPU.Label(mLabelName + "_AfterAddressCheck");
if (mTargetMethodInfo.Arguments[0].ArgumentType == typeof(object)) {
new CPUx86.Push("eax");

View file

@ -14,6 +14,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string mThisLabel;
private string mNextOpLabel;
private Type mCastAsType;
private int mCurrentILOffset;
public Castclass(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
Type xType = aReader.OperandValueType;
@ -23,7 +24,8 @@ namespace Indy.IL2CPU.IL.X86 {
mCastAsType = xType;
mTypeId = Engine.RegisterType(mCastAsType);
mThisLabel = GetInstructionLabel(aReader);
mNextOpLabel = GetInstructionLabel(aReader.Position);
mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
mCurrentILOffset = (int)aReader.Position;
}
public override void DoAssemble() {
@ -39,7 +41,7 @@ namespace Indy.IL2CPU.IL.X86 {
Assembler.StackContents.Push(new StackContent(4, true, false, false));
MethodBase xMethodIsInstance = Engine.GetMethodBase(Engine.GetType("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);

View file

@ -12,7 +12,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Ceq(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
NextInstructionLabel = GetInstructionLabel(aReader.Position);
NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
private void Assemble4Byte() {

View file

@ -13,7 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Cgt(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
NextInstructionLabel = GetInstructionLabel(aReader.Position);
NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
public override void DoAssemble() {

View file

@ -13,7 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Clt(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
NextInstructionLabel = GetInstructionLabel(aReader.Position);
NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
public override void DoAssemble() {

View file

@ -13,7 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Clt_Un(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
NextInstructionLabel = GetInstructionLabel(aReader.Position);
NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
public override void DoAssemble() {

View file

@ -13,6 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private int mTypeId;
private string mThisLabel;
private string mNextOpLabel;
private int mCurrentILOffset;
public Isinst(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
Type xType = aReader.OperandValueType;
@ -21,8 +22,9 @@ namespace Indy.IL2CPU.IL.X86 {
}
Type xTypeDef = xType;
mTypeId = Engine.RegisterType(xTypeDef);
mThisLabel = GetInstructionLabel(aReader.OldPosition);
mNextOpLabel = GetInstructionLabel(aReader.Position);
mThisLabel = GetInstructionLabel(aReader.Position);
mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
mCurrentILOffset = (int)aReader.Position;
}
public override void DoAssemble() {
@ -35,7 +37,7 @@ namespace Indy.IL2CPU.IL.X86 {
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);

View file

@ -15,22 +15,20 @@ namespace Indy.IL2CPU.IL.X86 {
public MethodBase CtorDef;
public string CurrentLabel;
public MethodInformation MethodInformation;
public Newobj()
: base(null, null) {
}
public int ILOffset;
public Newobj(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
CtorDef = aReader.OperandValueMethod;
CurrentLabel = GetInstructionLabel(aReader);
MethodInformation = aMethodInfo;
ILOffset = (int)aReader.Position;
}
public override void DoAssemble() {
Assemble(Assembler, ObjectUtilities.GetObjectStorageSize(CtorDef.DeclaringType), CtorDef, Engine.RegisterType(CtorDef.DeclaringType), CurrentLabel, MethodInformation);
Assemble(Assembler, ObjectUtilities.GetObjectStorageSize(CtorDef.DeclaringType), CtorDef, Engine.RegisterType(CtorDef.DeclaringType), CurrentLabel, MethodInformation, ILOffset);
}
public static void Assemble(Assembler.Assembler aAssembler, int aObjectSize, MethodBase aCtorDef, int aTypeId, string aCurrentLabel, MethodInformation aCurrentMethodInformation) {
public static void Assemble(Assembler.Assembler aAssembler, int aObjectSize, MethodBase aCtorDef, int aTypeId, string aCurrentLabel, MethodInformation aCurrentMethodInformation, int aCurrentILOffset) {
if (aCtorDef != null) {
Engine.QueueMethod(aCtorDef);
} else {
@ -103,7 +101,7 @@ namespace Indy.IL2CPU.IL.X86 {
foreach (var xStackInt in aAssembler.StackContents) {
new CPUx86.Add("esp", xStackInt.Size.ToString());
}
Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_4", false);
Call.EmitExceptionLogic(aAssembler, aCurrentILOffset, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_4", false);
new CPU.Label(aCurrentLabel + "_NO_ERROR_4");
new CPUx86.Pop(CPUx86.Registers.EAX);
// aAssembler.StackSizes.Pop();

View file

@ -19,18 +19,18 @@ namespace Indy.IL2CPU.IL.X86 {
/// </summary>
/// <param name="aAssembler"></param>
/// <param name="aAddress"></param>
public static void EmitCompareWithNull(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aAddress, string aCurrentLabel, string aNextLabel, Action aEmitCleanupMethod) {
public static void EmitCompareWithNull(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aAddress, string aCurrentLabel, string aNextLabel, Action aEmitCleanupMethod, int aCurrentILOffset) {
new CPUx86.Compare("dword " + aAddress, "0");
new CPUx86.JumpIfNotEquals(aNextLabel);
Type xNullRefExcType = typeof(NullReferenceException);
Newobj.Assemble(aAssembler, Engine.GetTypeInfo(xNullRefExcType).StorageSize, xNullRefExcType.GetConstructor(new Type[0]), Engine.RegisterType(xNullRefExcType), aCurrentLabel, aMethodInfo);
Newobj.Assemble(aAssembler, Engine.GetTypeInfo(xNullRefExcType).StorageSize, xNullRefExcType.GetConstructor(new Type[0]), Engine.RegisterType(xNullRefExcType), aCurrentLabel, aMethodInfo, aCurrentILOffset);
aAssembler.StackContents.Pop();
new CPUx86.Move("[" + DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax");
Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef);
new CPUx86.Call(Label.GenerateLabelName(CPU.Assembler.CurrentExceptionOccurredRef));
new CPUx86.Move("ecx", "3");
aEmitCleanupMethod();
Call.EmitExceptionLogic(aAssembler, aMethodInfo, aNextLabel, false);
Call.EmitExceptionLogic(aAssembler, aCurrentILOffset, aMethodInfo, aNextLabel, false);
}
public Op(ILReader aReader, MethodInformation aMethodInfo)
@ -65,7 +65,7 @@ namespace Indy.IL2CPU.IL.X86 {
mCatchType = null;
}
if (mCatchType != null && aMethodInfo != null && aMethodInfo.CurrentHandler != null && aMethodInfo.CurrentHandler.HandlerOffset > 0) {
mNeedsTypeCheck = aMethodInfo.CurrentHandler.HandlerOffset == aReader.Position;
mNeedsTypeCheck = aMethodInfo.CurrentHandler.HandlerOffset == aReader.NextPosition;
}
}

View file

@ -9,6 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string[] mAddresses;
protected void SetArgIndex(int aIndex, MethodInformation aMethodInfo) {
mAddresses = aMethodInfo.Arguments[aIndex].VirtualAddresses;
}
public Starg(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {

View file

@ -10,23 +10,25 @@ namespace Indy.IL2CPU.IL.X86 {
[OpCode(OpCodeEnum.Throw, false)]
public class Throw: Op {
private MethodInformation mMethodInfo;
private int mCurrentILOffset;
public Throw(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
mMethodInfo = aMethodInfo;
mCurrentILOffset = (int)aReader.Position;
}
public static void Assemble(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
public static void Assemble(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, int aCurrentILOffset) {
new CPUx86.Pop("eax");
new CPUx86.Move("[" + CPU.DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax");
Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef);
new CPUx86.Call(CPU.Label.GenerateLabelName(CPU.Assembler.CurrentExceptionOccurredRef));
new CPUx86.Move("ecx", "3");
Call.EmitExceptionLogic(aAssembler, aMethodInfo, null, false);
Call.EmitExceptionLogic(aAssembler,aCurrentILOffset, aMethodInfo, null, false);
aAssembler.StackContents.Pop();
}
public override void DoAssemble() {
Assemble(Assembler, mMethodInfo);
Assemble(Assembler, mMethodInfo, mCurrentILOffset);
}
}
}

View file

@ -15,6 +15,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string mNextOpLabel;
private Type mType;
private int mTypeSize;
private int mCurrentILOffset;
public Unbox(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
mType = aReader.OperandValueType;
@ -24,11 +25,12 @@ namespace Indy.IL2CPU.IL.X86 {
mTypeSize = Engine.GetFieldStorageSize(mType);
mTypeId = Engine.RegisterType(mType);
mThisLabel = GetInstructionLabel(aReader);
mNextOpLabel = GetInstructionLabel(aReader.Position);
mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
mCurrentILOffset = aReader.Position;
}
public override void DoAssemble() {
string mReturnNullLabel = mThisLabel + "_ReturnNull";
new CPUx86.Pop(CPUx86.Registers.EAX);
new CPUx86.Move(CPUx86.Registers.EAX, CPUx86.Registers.AtESP);
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfZero(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
@ -37,17 +39,26 @@ namespace Indy.IL2CPU.IL.X86 {
Assembler.StackContents.Push(new StackContent(4, typeof(uint)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(Engine.GetType("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);
Assembler.StackContents.Pop();
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfEquals(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.EAX);
new CPUx86.Pop(CPUx86.Registers.EAX);
int xSize = mTypeSize;
if (xSize % 4 > 0) {
xSize += 4 - (xSize % 4);
}
int xItems = xSize /4;
for (int i = xItems - 1; i >= 0; i--) {
new CPUx86.Push("[eax + " + ((i * 4) + ObjectImpl.FieldDataOffset) + "]");
}
Assembler.StackContents.Push(new StackContent(mTypeSize, mType));
new CPUx86.JumpAlways(mNextOpLabel);
new CPU.Label(mReturnNullLabel);
new CPUx86.Add(CPUx86.Registers.ESP, "4");
new CPUx86.Pushd("0");
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
}

View file

@ -21,7 +21,7 @@ namespace Indy.IL2CPU.IL.X86 {
Ldarg.Ldarg(Assembler, MethodInfo.Arguments[i]);
}
Engine.QueueMethod(aMethod);
Op xOp = new Call(aMethod);
Op xOp = new Call(aMethod,0);
xOp.Assembler = Assembler;
xOp.Assemble();
}

View file

@ -20,7 +20,7 @@ namespace Indy.IL2CPU.IL.X86 {
}
protected override void CallProxiedMethod() {
Op x = new Call(ProxiedMethod);
Op x = new Call(ProxiedMethod, 0);
x.Assembler = Assembler;
x.Assemble();
}

View file

@ -21,14 +21,14 @@ namespace Indy.IL2CPU.IL {
private byte[] mOperand;
private bool mHasOperand;
public long OldPosition {
public int Position {
get;
private set;
}
public long Position {
public int NextPosition {
get {
return mStream.Position;
return (int)mStream.Position;
}
}
@ -91,17 +91,17 @@ namespace Indy.IL2CPU.IL {
if (mOperandValueBranchPosition == null) {
//sbyte xTemp = (sbyte)mOperand;
//if (xTemp == mOperand) {
// mOperandValueBranchPosition = Position + xTemp;
// mOperandValueBranchPosition = NextPosition + xTemp;
//} else {
// if (mStream.Length < (Position + mOperand + 1)) {
// if (mStream.Length < (NextPosition + mOperand + 1)) {
// mOperandValueBranchPosition = (uint)mOperand;
// } else {
// mOperandValueBranchPosition = (uint)(Position + mOperand);
// mOperandValueBranchPosition = (uint)(NextPosition + mOperand);
// }
if (!mIsShortcut) {
mOperandValueBranchPosition = (uint?)(Position + OperandValueInt32);
mOperandValueBranchPosition = (uint?)(NextPosition + OperandValueInt32);
} else {
mOperandValueBranchPosition = (uint?)(Position + (sbyte)OperandValueInt32);
mOperandValueBranchPosition = (uint?)(NextPosition + (sbyte)OperandValueInt32);
}
//}
}
@ -183,7 +183,7 @@ namespace Indy.IL2CPU.IL {
}
public bool Read() {
OldPosition = Position;
Position = NextPosition;
int xByteValueInt = mStream.ReadByte();
OpCodeEnum xOpCode;
if (xByteValueInt == -1) {
@ -231,10 +231,10 @@ namespace Indy.IL2CPU.IL {
}
uint[] xResult = new uint[xBranchLocations1.Length];
for (int i = 0; i < xBranchLocations1.Length; i++) {
if ((Position + xBranchLocations1[i]) < 0) {
if ((NextPosition + xBranchLocations1[i]) < 0) {
xResult[i] = (uint)xBranchLocations1[i];
} else {
xResult[i] = (uint)(Position + xBranchLocations1[i]);
xResult[i] = (uint)(NextPosition + xBranchLocations1[i]);
}
}
OperandValueBranchLocations = xResult;

View file

@ -12,7 +12,7 @@ namespace Indy.IL2CPU.IL {
private readonly string mILComment;
private readonly bool mSupportsMetalMode;
public static string GetInstructionLabel(ILReader aReader) {
return GetInstructionLabel(aReader.OldPosition);
return GetInstructionLabel(aReader.Position);
}
public static string GetInstructionLabel(long aPosition) {
return ".L" + aPosition.ToString("X8");

View file

@ -411,7 +411,7 @@ namespace Indy.IL2CPU {
// GenericParameter xGenericParam = xArray.ElementType as GenericParameter;
// GenericParameter xFoundGenericParam = xFoundArray.ElementType as GenericParameter;
// if (xGenericParam != null && xFoundGenericParam != null) {
// if (xGenericParam.Position != xFoundGenericParam.Position) {
// if (xGenericParam.NextPosition != xFoundGenericParam.NextPosition) {
// continue;
// }
// }
@ -551,8 +551,8 @@ namespace Indy.IL2CPU {
public static int GetFieldStorageSize(Type aType) {
if (aType.FullName == "System.Void") {
return 0;
}
if (!aType.IsValueType && aType.IsClass) {
}
if ((!aType.IsValueType && aType.IsClass) || aType.IsInterface) {
return 4;
}
switch (aType.FullName) {
@ -766,12 +766,6 @@ namespace Indy.IL2CPU {
MethodBody xBody = xCurrentMethod.GetMethodBody();
// todo: add better detection of implementation state
if (xBody != null) {
// todo: add support for types which need different stack size
//foreach (LocalVariableInfo xLocal in xBody.LocalVariables) {
// if (xLocal.LocalType.IsValueType && !xLocal.LocalType.IsPrimitive && !xLocal.LocalType.IsEnum && !xLocal.LocalType.IsPointer) {
// throw new Exception("Structs as locals not yet supported!");
// }
//}
mInstructionsToSkip = 0;
mAssembler.StackContents.Clear();
ILReader xReader = new ILReader(xCurrentMethod);
@ -783,7 +777,7 @@ namespace Indy.IL2CPU {
ExceptionHandlingClause xCurrentHandler = null;
foreach (ExceptionHandlingClause xHandler in xBody.ExceptionHandlingClauses) {
if (xHandler.TryOffset > 0) {
if (xHandler.TryOffset <= xReader.Position && (xHandler.TryLength + xHandler.TryOffset) > xReader.Position) {
if (xHandler.TryOffset <= xReader.NextPosition && (xHandler.TryLength + xHandler.TryOffset) > xReader.NextPosition) {
if (xCurrentHandler == null) {
xCurrentHandler = xHandler;
continue;
@ -796,7 +790,7 @@ namespace Indy.IL2CPU {
}
}
if (xHandler.HandlerOffset > 0) {
if (xHandler.HandlerOffset <= xReader.Position && (xHandler.HandlerOffset + xHandler.HandlerLength) > xReader.Position) {
if (xHandler.HandlerOffset <= xReader.NextPosition && (xHandler.HandlerOffset + xHandler.HandlerLength) > xReader.NextPosition) {
if (xCurrentHandler == null) {
xCurrentHandler = xHandler;
continue;
@ -810,7 +804,7 @@ namespace Indy.IL2CPU {
}
if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0) {
if (xHandler.FilterOffset > 0) {
if (xHandler.FilterOffset <= xReader.Position) {
if (xHandler.FilterOffset <= xReader.NextPosition) {
if (xCurrentHandler == null) {
xCurrentHandler = xHandler;
continue;

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace NUnit.Framework {
public class Assertion {
public class AssertException:Exception {
public AssertException(string aMessage):base(aMessage) {
}
}
public static void AssertNotNull(string aMessage, object aObject) {
if (aObject == null) {
throw new AssertException(aMessage);
}
}
public static void Assert(string aMessage, bool aAssert) {
if (!aAssert) {
throw new AssertException(aMessage);
}
}
public static void Fail(string aMessage) {
throw new AssertException(aMessage);
}
public static void AssertEquals(string aMessage, int a, int b) {
if (a != b) {
Fail(aMessage);
}
}
public static void AssertEquals(string aMessage, object a, object b) {
if (!Object.Equals(a, b)) {
Fail(aMessage);
}
}
}
}

View file

@ -1,11 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using TestKernel;
namespace TestKernel {
namespace System {
[AttributeUsage(AttributeTargets.Class)]
public sealed class TestFixtureAttribute:Attribute {
public string BaseName {
get;
set;
}
}
[AttributeUsage(AttributeTargets.Method)]
public sealed class TestAttribute: Attribute {
public TestAttribute() {
TestGroup = TestGroups.NoInit;
}
public string TestGroup {
@ -13,7 +22,7 @@ namespace TestKernel {
set;
}
public string Description {
public string Name{
get;
set;
}
@ -23,4 +32,14 @@ namespace TestKernel {
set;
}
}
[AttributeUsage(AttributeTargets.Method)]
public sealed class ExpectedExceptionAttribute: Attribute {
public ExpectedExceptionAttribute(Type aException) {
Exception = aException;
}
public Type Exception {
get;
set;
}
}
}

View file

@ -6,36 +6,75 @@ using Cosmos.Build.Windows;
namespace TestKernel {
class Program {
private class TestInfo {
public Type ExpectedException;
public string Name;
public string TestGroup;
public bool IsExperimental;
}
[STAThread]
public static void Main(string[] aArgs) {
if (aArgs.Length == 0) {
var xBuilder = new Builder();
xBuilder.Build();
} else {
List<KeyValuePair<string, TestAttribute>> xTests = new List<KeyValuePair<string, TestAttribute>>();
List<KeyValuePair<string, TestInfo>> xTests = new List<KeyValuePair<string, TestInfo>>();
#region detect all current tests
foreach (var xType in typeof(Program).Assembly.GetTypes()) {
string xBaseName = "";
var xFixture = xType.GetCustomAttributes(typeof(TestFixtureAttribute), true).FirstOrDefault() as TestFixtureAttribute;
if (xFixture != null) {
xBaseName = xFixture.BaseName;
}
if (String.IsNullOrEmpty(xBaseName)) {
xBaseName = xType.FullName;
}
foreach (var xMethod in xType.GetMethods()) {
var xAttrib = xMethod.GetCustomAttributes(typeof(TestAttribute), true).FirstOrDefault() as TestAttribute;
if (xAttrib != null) {
xTests.Add(new KeyValuePair<string, TestAttribute>(xType.FullName.Replace('+', '.') + "." + xMethod.Name, xAttrib));
string xName = xAttrib.Name;
if (String.IsNullOrEmpty(xName)) {
xName = xBaseName + "." + xMethod.Name;
}
Type xExpectedException = null;
var xExpException = xMethod.GetCustomAttributes(typeof(ExpectedExceptionAttribute), true).FirstOrDefault() as ExpectedExceptionAttribute;
if (xExpException != null) {
xExpectedException = xExpException.Exception;
}
xTests.Add(new KeyValuePair<string, TestInfo>(xType.FullName.Replace('+', '.') + "." + xMethod.Name, new TestInfo() {
ExpectedException = xExpectedException,
Name = xName,
IsExperimental = xAttrib.IsExperimental,
TestGroup = xAttrib.TestGroup
}));
}
}
}
#endregion
Console.WriteLine("public static void Init() {");
Console.WriteLine("string xTestResult=null;");
Console.WriteLine("bool xError;");
foreach (var xTest in (from item in xTests
where item.Value.TestGroup == aArgs[0] && ((!item.Value.IsExperimental) || ((aArgs.Length > 1) && (aArgs[1] == "-experimental")))
select item)) {
Console.WriteLine("Console.WriteLine(\"Running test '{0}'\");", xTest.Value.Description);
Console.WriteLine("xTestResult = {0}();", xTest.Key);
where item.Value.TestGroup == aArgs[0] && ((!item.Value.IsExperimental) || ((aArgs.Length > 1) && (aArgs[1] == "-experimental")))
select item)) {
Console.WriteLine("Console.WriteLine(\"Running test '{0}'\");", xTest.Value.Name);
Console.WriteLine("try{");
Console.WriteLine("xError = false;");
Console.WriteLine("{0}();", xTest.Key);
if (xTest.Value.ExpectedException != null) {
Console.WriteLine("}}catch({0}){{", xTest.Value.ExpectedException.FullName.Replace("+", "."));
}
if (xTest.Value.ExpectedException != typeof(Exception)) {
Console.WriteLine("}catch(Exception E){");
Console.WriteLine("Console.Write(\" \");");
Console.WriteLine("Console.WriteLine(E.Message);");
Console.WriteLine("xError = true;");
}
Console.WriteLine("}");
Console.WriteLine("if(!xError){");
Console.WriteLine("Console.Write(\" \");");
Console.WriteLine("if (xTestResult == null) {");
Console.WriteLine("Console.WriteLine(\"Success\");");
Console.WriteLine("} else {");
Console.WriteLine("Console.Write(\"Error: \");");
Console.WriteLine("Console.WriteLine(xTestResult);}");
Console.WriteLine("}");
}
Console.WriteLine("Console.WriteLine(\"All tests executed!\");");
@ -47,14 +86,23 @@ namespace TestKernel {
public static void Init() {
string xTestResult = null;
Console.WriteLine("Running test 'System.String_EmbeddedStringContents'");
xTestResult = TestKernel.Tests.NoInit.StringTests.TestEmbedded();
Console.Write(" ");
if (xTestResult == null) {
bool xError;
Console.WriteLine("Running test 'Whoohoo'");
try {
xError = false;
TestKernel.Tests.NoInit.StringTests.OurTest();
} catch (Exception E) {
Console.Write(" ");
if (E == null) {
Console.WriteLine("<<NO EXCEPTION>>");
} else {
Console.WriteLine(E.Message);
}
xError = true;
}
if (!xError) {
Console.Write(" ");
Console.WriteLine("Success");
} else {
Console.Write("Error: ");
Console.WriteLine(xTestResult);
}
Console.WriteLine("All tests executed!");
while (true)

View file

@ -49,10 +49,12 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Assertion.cs" />
<Compile Include="Attributes.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestGroups.cs" />
<Compile Include="Tests\NoInit\mscorlib\System\ArrayListTest.cs" />
<Compile Include="Tests\NoInit\StringTests.cs" />
</ItemGroup>
<ItemGroup>

View file

@ -4,24 +4,10 @@ using System.Linq;
namespace TestKernel.Tests.NoInit {
public static class StringTests {
[Test(TestGroup=TestGroups.NoInit, Description="System.String_EmbeddedStringContents", IsExperimental=false)]
public static string TestEmbedded() {
string MyString = "Hello";
if (MyString == null)
return "MyString is null";
if (MyString.Length != 5)
return "MyString Length is not 5";
if (MyString[0] != 'H')
return "MyString[0] != 'H'";
if (MyString[1] != 'e')
return "MyString[1] != 'e'";
if (MyString[2] != 'l')
return "MyString[2] != 'l'";
if (MyString[3] != 'l')
return "MyString[3] != 'l'";
if (MyString[4] != 'o')
return "MyString[4] != 'o'";
return null;
[Test(Name="Whoohoo", TestGroup="Test")]
public static void OurTest() {
// succeeds
throw new Exception("Error");
}
}
}

File diff suppressed because it is too large Load diff