Some more ops are working now. Still working on the VTables support. Next Op to implement is Switch

This commit is contained in:
mterwoord_cp 2007-09-26 09:12:43 +00:00
parent 0f7c09b534
commit 1ea78b247f
21 changed files with 243 additions and 58 deletions

View file

@ -64,6 +64,7 @@
<Compile Include="JumpIfZero.cs" /> <Compile Include="JumpIfZero.cs" />
<Compile Include="Move.cs" /> <Compile Include="Move.cs" />
<Compile Include="Multiply.cs" /> <Compile Include="Multiply.cs" />
<Compile Include="Neg.cs" />
<Compile Include="Noop.cs" /> <Compile Include="Noop.cs" />
<Compile Include="Pop.cs" /> <Compile Include="Pop.cs" />
<Compile Include="Popd.cs" /> <Compile Include="Popd.cs" />

View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Indy.IL2CPU.Assembler.X86 {
[OpCode(0xFFFFFFFF, "neg")]
public class Neg: Instruction {
private string mDestination;
public Neg(string aDestination) {
mDestination = aDestination;
}
public override string ToString() {
return "neg " + mDestination;
}
}
}

View file

@ -19,17 +19,21 @@ namespace Indy.IL2CPU.IL.X86 {
throw new Exception("Couldn't determine Type!"); throw new Exception("Couldn't determine Type!");
} }
mTheSize = Engine.GetFieldStorageSize(xTypeRef); mTheSize = Engine.GetFieldStorageSize(xTypeRef);
if (mTheSize != 4) { if(((mTheSize/4)*4) != mTheSize) {
throw new Exception("Storage size not supported yet!"); throw new Exception("Incorrect Datasize. ( ((mTheSize / 4) * 4) === mTheSize should evaluate to true!");
} }
Engine.RegisterType(Engine.GetDefinitionFromTypeReference(xTypeRef)); Engine.RegisterType(Engine.GetDefinitionFromTypeReference(xTypeRef));
} }
public override void DoAssemble() { public override void DoAssemble() {
Pushd("0" + mTheSize.ToString("X").ToUpper() + "h"); Pushd("0" + (mTheSize + ObjectImpl.FieldDataOffset).ToString("X").ToUpper() + "h");
Call(new Label(RuntimeEngineRefs.Heap_AllocNewObjectRef).Name); Call(new Label(RuntimeEngineRefs.Heap_AllocNewObjectRef).Name);
Pushd("eax");
Move(Assembler, "dword [eax + 4]", "0" + InstanceTypeEnum.NormalObject.ToString("X") + "h"); Move(Assembler, "dword [eax + 4]", "0" + InstanceTypeEnum.NormalObject.ToString("X") + "h");
for (int i = 0; i < (mTheSize / 4); i++ ) {
Pop("edx");
Move(Assembler, "dword [eax + 0" + (ObjectImpl.FieldDataOffset + (i * 4)).ToString("X") + "h]", "edx");
}
Pushd("eax");
} }
} }
} }

View file

@ -2,16 +2,42 @@ using System;
using System.IO; using System.IO;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
using CPU = Indy.IL2CPU.Assembler.X86; using CPU = Indy.IL2CPU.Assembler;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Castclass, false)] [OpCode(Code.Castclass, false)]
public class Castclass: Op { public class Castclass: Op {
private int mTypeId;
private string mThisLabel;
private string mNextOpLabel;
public Castclass(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Castclass(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
TypeReference xType = aInstruction.Operand as TypeReference;
if(xType==null) {
throw new Exception("Unable to determine Type!");
} }
TypeDefinition xTypeDef = Engine.GetDefinitionFromTypeReference(xType);
mTypeId = Engine.RegisterType(xTypeDef);
mThisLabel = GetInstructionLabel(aInstruction);
mNextOpLabel = GetInstructionLabel(aInstruction.Next);
}
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: throw an exception when the class does not support the cast!
string mReturnNullLabel = mThisLabel + "_ReturnNull";
Pop("eax");
Compare("eax", "0");
JumpIfZero(mReturnNullLabel);
Pushd("[eax]", "0" + mTypeId + "h");
MethodDefinition xMethodIsInstance = Engine.GetMethodDefinition(Engine.GetTypeDefinition("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Call(new CPU.Label(xMethodIsInstance).Name);
Compare("eax", "0");
JumpIfEquals(mReturnNullLabel);
Pushd("eax");
JumpAlways(mNextOpLabel);
Label(mReturnNullLabel);
Pushd("0");
} }
} }
} }

View file

@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: implement correct truncating
} }
} }
} }

View file

@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: implement correct truncating
} }
} }
} }

View file

@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: implement correct conversion
} }
} }
} }

View file

@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: implement correct conversion
} }
} }
} }

View file

@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: implement correct truncating
} }
} }
} }

View file

@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); // todo: implement correct truncating
} }
} }
} }

View file

@ -2,16 +2,41 @@ using System;
using System.IO; using System.IO;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
using CPU = Indy.IL2CPU.Assembler.X86; using CPU = Indy.IL2CPU.Assembler;
using CPUx86 = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Isinst)] [OpCode(Code.Isinst)]
public class Isinst: Op { public class Isinst: Op {
private int mTypeId;
private string mThisLabel;
private string mNextOpLabel;
public Isinst(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Isinst(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
TypeReference xType = aInstruction.Operand as TypeReference;
if(xType==null) {
throw new Exception("Unable to determine Type!");
}
TypeDefinition xTypeDef = Engine.GetDefinitionFromTypeReference(xType);
mTypeId = Engine.RegisterType(xTypeDef);
mThisLabel = GetInstructionLabel(aInstruction);
mNextOpLabel = GetInstructionLabel(aInstruction.Next);
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); string mReturnNullLabel = mThisLabel + "_ReturnNull";
Pop("eax");
Compare("eax", "0");
JumpIfZero(mReturnNullLabel);
Pushd("[eax]", "0" + mTypeId + "h");
MethodDefinition xMethodIsInstance = Engine.GetMethodDefinition(Engine.GetTypeDefinition("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Call(new CPU.Label(xMethodIsInstance).Name);
Compare("eax", "0");
JumpIfEquals(mReturnNullLabel);
Pushd("eax");
JumpAlways(mNextOpLabel);
Label(mReturnNullLabel);
Pushd("0");
} }
} }
} }

View file

@ -12,14 +12,20 @@ namespace Indy.IL2CPU.IL.X86 {
public Ldtoken(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Ldtoken(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
FieldDefinition xFieldDef = aInstruction.Operand as FieldDefinition; FieldDefinition xFieldDef = aInstruction.Operand as FieldDefinition;
if (xFieldDef == null) { if (xFieldDef != null) {
throw new Exception("Unsupported Token type!");
}
if (!xFieldDef.IsStatic) { if (!xFieldDef.IsStatic) {
throw new Exception("Nonstatic field-backed tokens not supported yet!"); throw new Exception("Nonstatic field-backed tokens not supported yet!");
} }
Engine.QueueStaticField(xFieldDef); Engine.QueueStaticField(xFieldDef);
mTokenAddress = DataMember.GetStaticFieldName(xFieldDef); mTokenAddress = DataMember.GetStaticFieldName(xFieldDef);
return;
}
TypeReference xTypeRef = aInstruction.Operand as TypeReference;
if(xTypeRef!=null) {
mTokenAddress = "0" + Engine.RegisterType(Engine.GetDefinitionFromTypeReference(xTypeRef)).ToString("X") + "h";
return;
}
throw new Exception("Token type not supported yet!");
} }
public override void DoAssemble() { public override void DoAssemble() {

View file

@ -11,7 +11,9 @@ namespace Indy.IL2CPU.IL.X86 {
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); Pop("eax");
Assembler.Add(new CPU.Neg("eax"));
Pushd("eax");
} }
} }
} }

View file

@ -2,16 +2,41 @@ using System;
using System.IO; using System.IO;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil; using Mono.Cecil.Cil;
using CPU = Indy.IL2CPU.Assembler.X86; using CPU = Indy.IL2CPU.Assembler;
using CPUx86 = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Unbox)] [OpCode(Code.Unbox)]
public class Unbox: Op { public class Unbox: Op {
private int mTypeId;
private string mThisLabel;
private string mNextOpLabel;
public Unbox(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Unbox(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
TypeReference xType = aInstruction.Operand as TypeReference;
if(xType==null) {
throw new Exception("Unable to determine Type!");
}
TypeDefinition xTypeDef = Engine.GetDefinitionFromTypeReference(xType);
mTypeId = Engine.RegisterType(xTypeDef);
mThisLabel = GetInstructionLabel(aInstruction);
mNextOpLabel = GetInstructionLabel(aInstruction.Next);
} }
public override void DoAssemble() { public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!"); string mReturnNullLabel = mThisLabel + "_ReturnNull";
Pop("eax");
Compare("eax", "0");
JumpIfZero(mReturnNullLabel);
Pushd("[eax]", "0" + mTypeId + "h");
MethodDefinition xMethodIsInstance = Engine.GetMethodDefinition(Engine.GetTypeDefinition("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Call(new CPU.Label(xMethodIsInstance).Name);
Compare("eax", "0");
JumpIfEquals(mReturnNullLabel);
Pushd("eax");
JumpAlways(mNextOpLabel);
Label(mReturnNullLabel);
Pushd("0");
} }
} }
} }

View file

@ -6,12 +6,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 { namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Unbox_Any)] [OpCode(Code.Unbox_Any)]
public class Unbox_Any: Op { public class Unbox_Any: Unbox {
public Unbox_Any(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) public Unbox_Any(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) { : base(aInstruction, aMethodInfo) {
} }
public override void DoAssemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
}
} }
} }

View file

@ -45,9 +45,6 @@ namespace Indy.IL2CPU.IL {
} }
CallProxiedMethod(); CallProxiedMethod();
DoQueueMethod(ProxiedMethod); DoQueueMethod(ProxiedMethod);
if (MethodInfo.HasReturnValue) {
Ldloc(0);
}
} }
} }
} }

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Indy.IL2CPU.CustomImplementation.System {
public static class EnvironmentImpl {
[MethodAlias(Name = "System.Environment.GetResourceFromDefault(System.String)")]
public static string GetResourceFromDefault(string aResource) {
return aResource;
}
}
}

View file

@ -117,6 +117,7 @@ namespace Indy.IL2CPU {
IL.Op.QueueMethod += QueueMethod; IL.Op.QueueMethod += QueueMethod;
IL.Op.QueueStaticField += QueueStaticField; IL.Op.QueueStaticField += QueueStaticField;
try { try {
mTypes.Add(GetTypeDefinition("mscorlib", "System.Object"));
mMethods.Add(RuntimeEngineRefs.InitializeApplicationRef, false); mMethods.Add(RuntimeEngineRefs.InitializeApplicationRef, false);
mMethods.Add(RuntimeEngineRefs.FinalizeApplicationRef, false); mMethods.Add(RuntimeEngineRefs.FinalizeApplicationRef, false);
mMethods.Add(mCrawledAssembly.EntryPoint, false); mMethods.Add(mCrawledAssembly.EntryPoint, false);
@ -131,7 +132,14 @@ namespace Indy.IL2CPU {
} }
mAssembler.Add(new Assembler.X86.Call(new Label(RuntimeEngineRefs.FinalizeApplicationRef).Name)); mAssembler.Add(new Assembler.X86.Call(new Label(RuntimeEngineRefs.FinalizeApplicationRef).Name));
ProcessAllMethods(); ProcessAllMethods();
do {
int xOldCount = mMethods.Count;
ScanForMethodToIncludeForVMT(); ScanForMethodToIncludeForVMT();
ProcessAllMethods();
if (xOldCount == mMethods.Count) {
break;
}
} while (true);
ProcessAllStaticFields(); ProcessAllStaticFields();
} finally { } finally {
mAssembler.Flush(); mAssembler.Flush();
@ -145,15 +153,26 @@ namespace Indy.IL2CPU {
} }
private void ScanForMethodToIncludeForVMT() { private void ScanForMethodToIncludeForVMT() {
for (int i = mMethods.Count - 1; i >= 0; i--) { List<TypeDefinition> xCheckedTypes = new List<TypeDefinition>();
MethodDefinition xCurrentInspectedMethod = mMethods.Keys[i]; foreach (MethodDefinition xMethod in mMethods.Keys) {
TypeDefinition xCurrentType = GetDefinitionFromTypeReference(xCurrentInspectedMethod.DeclaringType); if (xMethod.IsStatic) {
while (xCurrentType != null) {
foreach (MethodDefinition xCurrentMethod in xCurrentType.Methods) {
if (xCurrentMethod.IsAbstract || xCurrentMethod.Overrides.Count > 0) {
QueueMethod(xCurrentMethod);
continue; continue;
} }
TypeDefinition xCurrentType = GetDefinitionFromTypeReference(xMethod.DeclaringType);
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) {
xCheckedTypes.Add(xCurrentType);
}
}
foreach (TypeDefinition xType in mTypes) {
if (!xCheckedTypes.Contains(xType, mTypesEqualityComparer)) {
xCheckedTypes.Add(xType);
}
}
for (int i = 0; i < xCheckedTypes.Count; i++) {
TypeDefinition xCurrentType = xCheckedTypes[i];
while (xCurrentType != null) {
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) {
xCheckedTypes.Add(xCurrentType);
} }
if (xCurrentType.FullName == "System.Object") { if (xCurrentType.FullName == "System.Object") {
break; break;
@ -161,6 +180,15 @@ namespace Indy.IL2CPU {
xCurrentType = GetDefinitionFromTypeReference(xCurrentType.BaseType); xCurrentType = GetDefinitionFromTypeReference(xCurrentType.BaseType);
} }
} }
foreach (TypeDefinition xTD in xCheckedTypes) {
foreach (MethodDefinition xMethod in xTD.Methods) {
if (!xMethod.IsStatic) {
if (xMethod.IsVirtual || xMethod.Overrides.Count > 0) {
QueueMethod(xMethod);
}
}
}
}
} }
public static MethodDefinition GetDefinitionFromMethodReference(MethodReference aRef) { public static MethodDefinition GetDefinitionFromMethodReference(MethodReference aRef) {
@ -177,15 +205,19 @@ namespace Indy.IL2CPU {
} }
public static TypeDefinition GetDefinitionFromTypeReference(TypeReference aRef) { public static TypeDefinition GetDefinitionFromTypeReference(TypeReference aRef) {
if (aRef == null) {
throw new ArgumentNullException("aRef");
}
if (mCurrent == null) { if (mCurrent == null) {
throw new Exception("No Current engine found!"); throw new Exception("No Current engine found!");
} }
TypeDefinition xTempResult = aRef as TypeDefinition;
if (xTempResult != null) {
return xTempResult;
}
if (aRef.FullName.Contains("modreq")) { if (aRef.FullName.Contains("modreq")) {
aRef = aRef.GetOriginalType(); aRef = aRef.GetOriginalType();
} }
if (aRef.FullName.EndsWith("[]")) {
return GetTypeDefinition(aRef.Module.Assembly.Name.Name, aRef.FullName.Substring(0, aRef.FullName.Length - 2));
}
AssemblyNameReference xAssemblyNameReference = aRef.Scope as AssemblyNameReference; AssemblyNameReference xAssemblyNameReference = aRef.Scope as AssemblyNameReference;
if (xAssemblyNameReference != null) { if (xAssemblyNameReference != null) {
AssemblyDefinition xReferencedFieldAssembly; AssemblyDefinition xReferencedFieldAssembly;
@ -200,6 +232,12 @@ namespace Indy.IL2CPU {
if (xReferencedType != null) { if (xReferencedType != null) {
return xReferencedType; return xReferencedType;
} }
if (aRef.FullName.EndsWith("[]")) {
xReferencedType = xModule.Types[aRef.FullName.Substring(0, aRef.FullName.Length - 2)];
if (xReferencedType != null) {
return xReferencedType;
}
}
} }
} }
} else { } else {
@ -209,6 +247,12 @@ namespace Indy.IL2CPU {
if (xReferencedType != null) { if (xReferencedType != null) {
return xReferencedType; return xReferencedType;
} }
if (aRef.FullName.EndsWith("[]")) {
xReferencedType = xReferencedModule.Types[aRef.FullName.Substring(0, aRef.FullName.Length - 2)];
if (xReferencedType != null) {
return xReferencedType;
}
}
} else { } else {
mCurrent.OnDebugLog("Error: Unhandled scope: " + aRef.Scope == null ? "**NULL**" : aRef.Scope.GetType().FullName); mCurrent.OnDebugLog("Error: Unhandled scope: " + aRef.Scope == null ? "**NULL**" : aRef.Scope.GetType().FullName);
} }
@ -228,13 +272,13 @@ namespace Indy.IL2CPU {
} }
switch (aType.FullName) { switch (aType.FullName) {
case "System.Char": case "System.Char":
return 2; return 4;
case "System.Byte": case "System.Byte":
case "System.SByte": case "System.SByte":
return 1; return 4;
case "System.UInt16": case "System.UInt16":
case "System.Int16": case "System.Int16":
return 2; return 4;
case "System.UInt32": case "System.UInt32":
case "System.Int32": case "System.Int32":
return 4; return 4;
@ -245,8 +289,20 @@ namespace Indy.IL2CPU {
case "System.UIntPtr": case "System.UIntPtr":
case "System.IntPtr": case "System.IntPtr":
return 4; return 4;
case "System.Boolean":
return 4;
case "System.Single":
return 4;
case "System.Double":
return 8;
case "System.Decimal":
return 16;
case "System.Guid":
return 16;
case "System.DateTime":
return 8; // todo: check for correct size
} }
throw new Exception("Unable to determine ValueType size!"); throw new Exception("Unable to determine ValueType size! (Type = " + aType.FullName + ")");
} }
private void ProcessAllStaticFields() { private void ProcessAllStaticFields() {
@ -458,8 +514,6 @@ namespace Indy.IL2CPU {
} }
public static SortedList<string, TypeInformation.Field> GetTypeFieldInfo(MethodDefinition aCurrentMethod, out uint aObjectStorageSize) { public static SortedList<string, TypeInformation.Field> GetTypeFieldInfo(MethodDefinition aCurrentMethod, out uint aObjectStorageSize) {
SortedList<string, TypeInformation.Field> xTypeFields = new SortedList<string, TypeInformation.Field>();
aObjectStorageSize = ObjectImpl.FieldDataOffset;
TypeDefinition xCurrentInspectedType = GetDefinitionFromTypeReference(aCurrentMethod.DeclaringType); TypeDefinition xCurrentInspectedType = GetDefinitionFromTypeReference(aCurrentMethod.DeclaringType);
return GetTypeFieldInfo(xCurrentInspectedType, out aObjectStorageSize); return GetTypeFieldInfo(xCurrentInspectedType, out aObjectStorageSize);
} }
@ -483,7 +537,7 @@ namespace Indy.IL2CPU {
xTypeFields.Add(xField.ToString(), new TypeInformation.Field(aObjectStorageSize, xFieldSize)); xTypeFields.Add(xField.ToString(), new TypeInformation.Field(aObjectStorageSize, xFieldSize));
aObjectStorageSize += xFieldSize; aObjectStorageSize += xFieldSize;
} }
if (aType.FullName != "System.Object") { if (aType.FullName != "System.Object" && aType.BaseType != null) {
aType = GetDefinitionFromTypeReference(aType.BaseType); aType = GetDefinitionFromTypeReference(aType.BaseType);
} else { } else {
break; break;
@ -596,13 +650,16 @@ namespace Indy.IL2CPU {
/// <param name="aType"></param> /// <param name="aType"></param>
/// <returns></returns> /// <returns></returns>
public static int RegisterType(TypeDefinition aType) { public static int RegisterType(TypeDefinition aType) {
if (aType == null) {
throw new ArgumentNullException("aType");
}
if (mCurrent == null) { if (mCurrent == null) {
throw new Exception("ERROR: No Current Engine found!"); throw new Exception("ERROR: No Current Engine found!");
} }
TypeDefinition xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName)); TypeDefinition xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName));
if (xFoundItem == null) { if (xFoundItem == null) {
mCurrent.mTypes.Add(aType); mCurrent.mTypes.Add(aType);
if (aType.FullName != "System.Object") { if (aType.FullName != "System.Object" && aType.BaseType != null) {
TypeDefinition xCurInspectedType = GetDefinitionFromTypeReference(aType.BaseType); TypeDefinition xCurInspectedType = GetDefinitionFromTypeReference(aType.BaseType);
RegisterType(xCurInspectedType); RegisterType(xCurInspectedType);
} }

View file

@ -77,6 +77,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CustomImplementation\System\ArrayImpl.cs" /> <Compile Include="CustomImplementation\System\ArrayImpl.cs" />
<Compile Include="CustomImplementation\System\EnvironmentImpl.cs" />
<Compile Include="CustomImplementation\System\StringImpl.cs" /> <Compile Include="CustomImplementation\System\StringImpl.cs" />
<Compile Include="VTablesImpl.cs" /> <Compile Include="VTablesImpl.cs" />
</ItemGroup> </ItemGroup>

View file

@ -5,12 +5,26 @@ using System.Text;
namespace Indy.IL2CPU { namespace Indy.IL2CPU {
public static class VTablesImpl { public static class VTablesImpl {
// method VTable, indexed by the type public struct VTable {
/// <summary> public int TypeIdentifier;
/// This array contains a list of types in the first dimension and a list public int BaseTypeIdentifier;
/// of method indexes in the second dimension. public int[] MethodIndexes;
/// </summary> public int[] MethodAddresses;
private static IntPtr[][] mMethods; }
private static VTable[] mTypes;
public static bool IsInstance(int aObjectType, int aDesiredObjectType) {
int xCurrentType = aObjectType;
if (aObjectType == 0) {
return true;
}
do {
if (xCurrentType == aDesiredObjectType) {
return true;
}
xCurrentType = mTypes[xCurrentType].BaseTypeIdentifier;
} while (xCurrentType != 0);
return false;
}
} }
} }