mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-20 04:48:53 +00:00
Some more ops are working now. Still working on the VTables support. Next Op to implement is Switch
This commit is contained in:
parent
0f7c09b534
commit
1ea78b247f
21 changed files with 243 additions and 58 deletions
|
|
@ -64,6 +64,7 @@
|
|||
<Compile Include="JumpIfZero.cs" />
|
||||
<Compile Include="Move.cs" />
|
||||
<Compile Include="Multiply.cs" />
|
||||
<Compile Include="Neg.cs" />
|
||||
<Compile Include="Noop.cs" />
|
||||
<Compile Include="Pop.cs" />
|
||||
<Compile Include="Popd.cs" />
|
||||
|
|
|
|||
17
source/Indy.IL2CPU.Assembler.X86/Neg.cs
Normal file
17
source/Indy.IL2CPU.Assembler.X86/Neg.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,17 +19,21 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
throw new Exception("Couldn't determine Type!");
|
||||
}
|
||||
mTheSize = Engine.GetFieldStorageSize(xTypeRef);
|
||||
if (mTheSize != 4) {
|
||||
throw new Exception("Storage size not supported yet!");
|
||||
if(((mTheSize/4)*4) != mTheSize) {
|
||||
throw new Exception("Incorrect Datasize. ( ((mTheSize / 4) * 4) === mTheSize should evaluate to true!");
|
||||
}
|
||||
Engine.RegisterType(Engine.GetDefinitionFromTypeReference(xTypeRef));
|
||||
}
|
||||
|
||||
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);
|
||||
Pushd("eax");
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,42 @@ using System;
|
|||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
using CPU = Indy.IL2CPU.Assembler.X86;
|
||||
using CPU = Indy.IL2CPU.Assembler;
|
||||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Castclass, false)]
|
||||
public class Castclass: Op {
|
||||
private int mTypeId;
|
||||
private string mThisLabel;
|
||||
private string mNextOpLabel;
|
||||
public Castclass(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation 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() {
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
// todo: implement correct truncating
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
// todo: implement correct truncating
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
// todo: implement correct conversion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
// todo: implement correct conversion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
// todo: implement correct truncating
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
// todo: implement correct truncating
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,41 @@ using System;
|
|||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
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 {
|
||||
[OpCode(Code.Isinst)]
|
||||
public class Isinst: Op {
|
||||
private int mTypeId;
|
||||
private string mThisLabel;
|
||||
private string mNextOpLabel;
|
||||
public Isinst(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation 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() {
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,8 +15,8 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
}
|
||||
string xFieldId = xField.ToString();
|
||||
TypeInformation.Field xTheField;
|
||||
uint xStorageSize;
|
||||
xTheField = Engine.GetTypeFieldInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType), out xStorageSize)[xFieldId];
|
||||
uint xStorageSize;
|
||||
xTheField = Engine.GetTypeFieldInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType), out xStorageSize)[xFieldId];
|
||||
RelativeAddress = xTheField.RelativeAddress;
|
||||
FieldSize = xTheField.Size;
|
||||
if (FieldSize != 4) {
|
||||
|
|
|
|||
|
|
@ -12,14 +12,20 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
public Ldtoken(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
FieldDefinition xFieldDef = aInstruction.Operand as FieldDefinition;
|
||||
if (xFieldDef == null) {
|
||||
throw new Exception("Unsupported Token type!");
|
||||
if (xFieldDef != null) {
|
||||
if (!xFieldDef.IsStatic) {
|
||||
throw new Exception("Nonstatic field-backed tokens not supported yet!");
|
||||
}
|
||||
Engine.QueueStaticField(xFieldDef);
|
||||
mTokenAddress = DataMember.GetStaticFieldName(xFieldDef);
|
||||
return;
|
||||
}
|
||||
if (!xFieldDef.IsStatic) {
|
||||
throw new Exception("Nonstatic field-backed tokens not supported yet!");
|
||||
TypeReference xTypeRef = aInstruction.Operand as TypeReference;
|
||||
if(xTypeRef!=null) {
|
||||
mTokenAddress = "0" + Engine.RegisterType(Engine.GetDefinitionFromTypeReference(xTypeRef)).ToString("X") + "h";
|
||||
return;
|
||||
}
|
||||
Engine.QueueStaticField(xFieldDef);
|
||||
mTokenAddress=DataMember.GetStaticFieldName(xFieldDef);
|
||||
throw new Exception("Token type not supported yet!");
|
||||
}
|
||||
|
||||
public override void DoAssemble() {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ namespace Indy.IL2CPU.IL.X86 {
|
|||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,41 @@ using System;
|
|||
using System.IO;
|
||||
using Mono.Cecil;
|
||||
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 {
|
||||
[OpCode(Code.Unbox)]
|
||||
public class Unbox: Op {
|
||||
private int mTypeId;
|
||||
private string mThisLabel;
|
||||
private string mNextOpLabel;
|
||||
public Unbox(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation 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() {
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
|
|||
|
||||
namespace Indy.IL2CPU.IL.X86 {
|
||||
[OpCode(Code.Unbox_Any)]
|
||||
public class Unbox_Any: Op {
|
||||
public class Unbox_Any: Unbox {
|
||||
public Unbox_Any(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
|
||||
: base(aInstruction, aMethodInfo) {
|
||||
}
|
||||
public override void DoAssemble() {
|
||||
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -45,9 +45,6 @@ namespace Indy.IL2CPU.IL {
|
|||
}
|
||||
CallProxiedMethod();
|
||||
DoQueueMethod(ProxiedMethod);
|
||||
if (MethodInfo.HasReturnValue) {
|
||||
Ldloc(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,6 +117,7 @@ namespace Indy.IL2CPU {
|
|||
IL.Op.QueueMethod += QueueMethod;
|
||||
IL.Op.QueueStaticField += QueueStaticField;
|
||||
try {
|
||||
mTypes.Add(GetTypeDefinition("mscorlib", "System.Object"));
|
||||
mMethods.Add(RuntimeEngineRefs.InitializeApplicationRef, false);
|
||||
mMethods.Add(RuntimeEngineRefs.FinalizeApplicationRef, false);
|
||||
mMethods.Add(mCrawledAssembly.EntryPoint, false);
|
||||
|
|
@ -131,7 +132,14 @@ namespace Indy.IL2CPU {
|
|||
}
|
||||
mAssembler.Add(new Assembler.X86.Call(new Label(RuntimeEngineRefs.FinalizeApplicationRef).Name));
|
||||
ProcessAllMethods();
|
||||
ScanForMethodToIncludeForVMT();
|
||||
do {
|
||||
int xOldCount = mMethods.Count;
|
||||
ScanForMethodToIncludeForVMT();
|
||||
ProcessAllMethods();
|
||||
if (xOldCount == mMethods.Count) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
ProcessAllStaticFields();
|
||||
} finally {
|
||||
mAssembler.Flush();
|
||||
|
|
@ -145,15 +153,26 @@ namespace Indy.IL2CPU {
|
|||
}
|
||||
|
||||
private void ScanForMethodToIncludeForVMT() {
|
||||
for (int i = mMethods.Count - 1; i >= 0; i--) {
|
||||
MethodDefinition xCurrentInspectedMethod = mMethods.Keys[i];
|
||||
TypeDefinition xCurrentType = GetDefinitionFromTypeReference(xCurrentInspectedMethod.DeclaringType);
|
||||
List<TypeDefinition> xCheckedTypes = new List<TypeDefinition>();
|
||||
foreach (MethodDefinition xMethod in mMethods.Keys) {
|
||||
if (xMethod.IsStatic) {
|
||||
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) {
|
||||
foreach (MethodDefinition xCurrentMethod in xCurrentType.Methods) {
|
||||
if (xCurrentMethod.IsAbstract || xCurrentMethod.Overrides.Count > 0) {
|
||||
QueueMethod(xCurrentMethod);
|
||||
continue;
|
||||
}
|
||||
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) {
|
||||
xCheckedTypes.Add(xCurrentType);
|
||||
}
|
||||
if (xCurrentType.FullName == "System.Object") {
|
||||
break;
|
||||
|
|
@ -161,6 +180,15 @@ namespace Indy.IL2CPU {
|
|||
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) {
|
||||
|
|
@ -177,15 +205,19 @@ namespace Indy.IL2CPU {
|
|||
}
|
||||
|
||||
public static TypeDefinition GetDefinitionFromTypeReference(TypeReference aRef) {
|
||||
if (aRef == null) {
|
||||
throw new ArgumentNullException("aRef");
|
||||
}
|
||||
if (mCurrent == null) {
|
||||
throw new Exception("No Current engine found!");
|
||||
}
|
||||
TypeDefinition xTempResult = aRef as TypeDefinition;
|
||||
if (xTempResult != null) {
|
||||
return xTempResult;
|
||||
}
|
||||
if (aRef.FullName.Contains("modreq")) {
|
||||
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;
|
||||
if (xAssemblyNameReference != null) {
|
||||
AssemblyDefinition xReferencedFieldAssembly;
|
||||
|
|
@ -200,6 +232,12 @@ namespace Indy.IL2CPU {
|
|||
if (xReferencedType != null) {
|
||||
return xReferencedType;
|
||||
}
|
||||
if (aRef.FullName.EndsWith("[]")) {
|
||||
xReferencedType = xModule.Types[aRef.FullName.Substring(0, aRef.FullName.Length - 2)];
|
||||
if (xReferencedType != null) {
|
||||
return xReferencedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -209,6 +247,12 @@ namespace Indy.IL2CPU {
|
|||
if (xReferencedType != null) {
|
||||
return xReferencedType;
|
||||
}
|
||||
if (aRef.FullName.EndsWith("[]")) {
|
||||
xReferencedType = xReferencedModule.Types[aRef.FullName.Substring(0, aRef.FullName.Length - 2)];
|
||||
if (xReferencedType != null) {
|
||||
return xReferencedType;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mCurrent.OnDebugLog("Error: Unhandled scope: " + aRef.Scope == null ? "**NULL**" : aRef.Scope.GetType().FullName);
|
||||
}
|
||||
|
|
@ -228,13 +272,13 @@ namespace Indy.IL2CPU {
|
|||
}
|
||||
switch (aType.FullName) {
|
||||
case "System.Char":
|
||||
return 2;
|
||||
return 4;
|
||||
case "System.Byte":
|
||||
case "System.SByte":
|
||||
return 1;
|
||||
return 4;
|
||||
case "System.UInt16":
|
||||
case "System.Int16":
|
||||
return 2;
|
||||
return 4;
|
||||
case "System.UInt32":
|
||||
case "System.Int32":
|
||||
return 4;
|
||||
|
|
@ -245,8 +289,20 @@ namespace Indy.IL2CPU {
|
|||
case "System.UIntPtr":
|
||||
case "System.IntPtr":
|
||||
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() {
|
||||
|
|
@ -458,8 +514,6 @@ namespace Indy.IL2CPU {
|
|||
}
|
||||
|
||||
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);
|
||||
return GetTypeFieldInfo(xCurrentInspectedType, out aObjectStorageSize);
|
||||
}
|
||||
|
|
@ -483,7 +537,7 @@ namespace Indy.IL2CPU {
|
|||
xTypeFields.Add(xField.ToString(), new TypeInformation.Field(aObjectStorageSize, xFieldSize));
|
||||
aObjectStorageSize += xFieldSize;
|
||||
}
|
||||
if (aType.FullName != "System.Object") {
|
||||
if (aType.FullName != "System.Object" && aType.BaseType != null) {
|
||||
aType = GetDefinitionFromTypeReference(aType.BaseType);
|
||||
} else {
|
||||
break;
|
||||
|
|
@ -596,13 +650,16 @@ namespace Indy.IL2CPU {
|
|||
/// <param name="aType"></param>
|
||||
/// <returns></returns>
|
||||
public static int RegisterType(TypeDefinition aType) {
|
||||
if (aType == null) {
|
||||
throw new ArgumentNullException("aType");
|
||||
}
|
||||
if (mCurrent == null) {
|
||||
throw new Exception("ERROR: No Current Engine found!");
|
||||
}
|
||||
TypeDefinition xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName));
|
||||
if (xFoundItem == null) {
|
||||
mCurrent.mTypes.Add(aType);
|
||||
if (aType.FullName != "System.Object") {
|
||||
if (aType.FullName != "System.Object" && aType.BaseType != null) {
|
||||
TypeDefinition xCurInspectedType = GetDefinitionFromTypeReference(aType.BaseType);
|
||||
RegisterType(xCurInspectedType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CustomImplementation\System\ArrayImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\EnvironmentImpl.cs" />
|
||||
<Compile Include="CustomImplementation\System\StringImpl.cs" />
|
||||
<Compile Include="VTablesImpl.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -5,12 +5,26 @@ using System.Text;
|
|||
|
||||
namespace Indy.IL2CPU {
|
||||
public static class VTablesImpl {
|
||||
// method VTable, indexed by the type
|
||||
/// <summary>
|
||||
/// This array contains a list of types in the first dimension and a list
|
||||
/// of method indexes in the second dimension.
|
||||
/// </summary>
|
||||
private static IntPtr[][] mMethods;
|
||||
public struct VTable {
|
||||
public int TypeIdentifier;
|
||||
public int BaseTypeIdentifier;
|
||||
public int[] MethodIndexes;
|
||||
public int[] MethodAddresses;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue