mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-10 10:11:31 +00:00
Fixed exceptions
This commit is contained in:
parent
1a9805a18a
commit
edac084b3d
26 changed files with 2175 additions and 112 deletions
|
|
@ -54,7 +54,6 @@ namespace Indy.IL2CPU.Assembler {
|
|||
}
|
||||
|
||||
public static void ExceptionOccurred() {
|
||||
Console.WriteLine("Exception Occurred!");
|
||||
System.Diagnostics.Debugger.Break();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
36
source/TestKernel/Assertion.cs
Normal file
36
source/TestKernel/Assertion.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
1963
source/TestKernel/Tests/NoInit/mscorlib/System/ArrayListTest.cs
Normal file
1963
source/TestKernel/Tests/NoInit/mscorlib/System/ArrayListTest.cs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue