mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +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="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" />
|
||||||
|
|
|
||||||
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!");
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -45,9 +45,6 @@ namespace Indy.IL2CPU.IL {
|
||||||
}
|
}
|
||||||
CallProxiedMethod();
|
CallProxiedMethod();
|
||||||
DoQueueMethod(ProxiedMethod);
|
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.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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue