mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
154 lines
No EOL
4.3 KiB
C#
154 lines
No EOL
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Indy.IL2CPU {
|
|
public static class VTablesImpl {
|
|
// this field seems to be always empty, but the VTablesImpl class is embedded in the final exe.
|
|
public 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;
|
|
}
|
|
if (xCurrentType == mTypes[xCurrentType].BaseTypeIdentifier) {
|
|
return false;
|
|
}
|
|
xCurrentType = mTypes[xCurrentType].BaseTypeIdentifier;
|
|
} while (xCurrentType != 0);
|
|
return false;
|
|
}
|
|
|
|
public static void LoadTypeTable(int aTypeCount) {
|
|
//mTypes = new VTable[aTypeCount];
|
|
}
|
|
|
|
public static void SetTypeInfo(int aType, int aBaseType, int[] aMethodIndexes, int[] aMethodAddresses, char[] aName) {
|
|
mTypes[aType] = new VTable();
|
|
mTypes[aType].BaseTypeIdentifier = aBaseType;
|
|
mTypes[aType].MethodIndexes = aMethodIndexes;
|
|
mTypes[aType].MethodAddresses = aMethodAddresses;
|
|
mTypes[aType].Name = aName;
|
|
}
|
|
|
|
public static string GetTypeName(int aType) {
|
|
return new String(mTypes[aType].Name);
|
|
}
|
|
|
|
public static void SetMethodInfo(int aType, int aMethodIndex, int aMethodIdentifier, int aMethodAddress, char[] aName) {
|
|
mTypes[aType].MethodIndexes[aMethodIndex] = aMethodIdentifier;
|
|
mTypes[aType].MethodAddresses[aMethodIndex] = aMethodAddress;
|
|
}
|
|
|
|
private static void WriteNumber(uint aValue, byte aBitCount) {
|
|
uint xValue = aValue;
|
|
byte xCurrentBits = aBitCount;
|
|
Console.Write("0x");
|
|
while (xCurrentBits >= 4) {
|
|
xCurrentBits -= 4;
|
|
byte xCurrentDigit = (byte)((xValue >> xCurrentBits) & 0xF);
|
|
string xDigitString = null;
|
|
switch (xCurrentDigit) {
|
|
case 0:
|
|
xDigitString = "0";
|
|
goto default;
|
|
case 1:
|
|
xDigitString = "1";
|
|
goto default;
|
|
case 2:
|
|
xDigitString = "2";
|
|
goto default;
|
|
case 3:
|
|
xDigitString = "3";
|
|
goto default;
|
|
case 4:
|
|
xDigitString = "4";
|
|
goto default;
|
|
case 5:
|
|
xDigitString = "5";
|
|
goto default;
|
|
case 6:
|
|
xDigitString = "6";
|
|
goto default;
|
|
case 7:
|
|
xDigitString = "7";
|
|
goto default;
|
|
case 8:
|
|
xDigitString = "8";
|
|
goto default;
|
|
case 9:
|
|
xDigitString = "9";
|
|
goto default;
|
|
case 10:
|
|
xDigitString = "A";
|
|
goto default;
|
|
case 11:
|
|
xDigitString = "B";
|
|
goto default;
|
|
case 12:
|
|
xDigitString = "C";
|
|
goto default;
|
|
case 13:
|
|
xDigitString = "D";
|
|
goto default;
|
|
case 14:
|
|
xDigitString = "E";
|
|
goto default;
|
|
case 15:
|
|
xDigitString = "F";
|
|
goto default;
|
|
default:
|
|
Console.Write(xDigitString);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static int GetMethodAddressForType(int aType, int aMethodIndex) {
|
|
if (aType == 0) {
|
|
for (int i = 0; i < mTypes[0].MethodIndexes.Length; i++) {
|
|
if (mTypes[0].MethodIndexes[i] == aMethodIndex) {
|
|
return mTypes[0].MethodAddresses[i];
|
|
}
|
|
}
|
|
} else {
|
|
//Console.WriteLine("Checking for MethodAddress");
|
|
//Console.Write(" Type = ");
|
|
//Console.Write(aType.ToString());
|
|
//Console.Write(", Method = ");
|
|
//Console.WriteLine(aMethodIndex.ToString());
|
|
do {
|
|
//Console.Write("Checking type ");
|
|
//Console.WriteLine(aType.ToString());
|
|
for (int i = 0; i < mTypes[aType].MethodIndexes.Length; i++) {
|
|
//Console.Write(" ");
|
|
//Console.WriteLine(mTypes[aType].MethodIndexes[i].ToString());
|
|
if (mTypes[aType].MethodIndexes[i] == aMethodIndex) {
|
|
//Console.WriteLine("Found!");
|
|
return mTypes[aType].MethodAddresses[i];
|
|
}
|
|
}
|
|
aType = mTypes[aType].BaseTypeIdentifier;
|
|
} while (aType != 0);
|
|
}
|
|
throw new Exception("Cannot find virtual method!");
|
|
}
|
|
}
|
|
[StructLayout(LayoutKind.Explicit, Size = 16)]
|
|
public struct VTable {
|
|
[FieldOffset(0)]
|
|
public int BaseTypeIdentifier;
|
|
[FieldOffset(4)]
|
|
public char[] Name;
|
|
[FieldOffset(8)]
|
|
public int[] MethodIndexes;
|
|
[FieldOffset(12)]
|
|
public int[] MethodAddresses;
|
|
}
|
|
} |