mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 14:02:19 +00:00
This commit is contained in:
parent
feffd92821
commit
1d146df185
7 changed files with 496 additions and 323 deletions
|
|
@ -8,326 +8,238 @@ using System.Reflection;
|
||||||
using Indy.IL2CPU.Compiler;
|
using Indy.IL2CPU.Compiler;
|
||||||
|
|
||||||
namespace Indy.IL2CPU.IL {
|
namespace Indy.IL2CPU.IL {
|
||||||
public class MethodBaseComparer : IComparer<MethodBase>, IEqualityComparer<MethodBase>
|
public class MethodBaseComparer: IComparer<MethodBase>, IEqualityComparer<MethodBase> {
|
||||||
{
|
#region IComparer<MethodBase> Members
|
||||||
#region IComparer<MethodBase> Members
|
public int Compare(MethodBase x, MethodBase y) {
|
||||||
public int Compare(MethodBase x, MethodBase y)
|
return x.GetFullName().CompareTo(y.GetFullName());
|
||||||
{
|
|
||||||
return x.GetFullName().CompareTo(y.GetFullName());
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public bool Equals(MethodBase x, MethodBase y)
|
|
||||||
{
|
|
||||||
return Compare(x, y) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetHashCode(MethodBase obj)
|
|
||||||
{
|
|
||||||
return obj.GetFullName().GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public abstract class InitVmtImplementationOp: Op {
|
#endregion
|
||||||
public delegate int GetMethodIdentifierEventHandler(MethodBase aMethod);
|
|
||||||
public InitVmtImplementationOp(ILReader aReader, MethodInformation aMethodInfo)
|
public bool Equals(MethodBase x, MethodBase y) {
|
||||||
: base(aReader, aMethodInfo) {
|
return Compare(x, y) == 0;
|
||||||
}
|
}
|
||||||
private static readonly bool mDebugMode = false;
|
|
||||||
static InitVmtImplementationOp() {
|
public int GetHashCode(MethodBase obj) {
|
||||||
// flag for conditional debug code for Matthijs, please leave it.
|
return obj.GetFullName().GetHashCode();
|
||||||
mDebugMode = Environment.MachineName.Equals("laptop-matthijs", StringComparison.InvariantCultureIgnoreCase);
|
}
|
||||||
|
}
|
||||||
|
public abstract class InitVmtImplementationOp: Op {
|
||||||
|
public delegate int GetMethodIdentifierEventHandler(MethodBase aMethod);
|
||||||
|
public InitVmtImplementationOp(ILReader aReader, MethodInformation aMethodInfo)
|
||||||
|
: base(aReader, aMethodInfo) {
|
||||||
|
}
|
||||||
|
private static readonly bool mDebugMode = false;
|
||||||
|
static InitVmtImplementationOp() {
|
||||||
|
// flag for conditional debug code for Matthijs, please leave it.
|
||||||
|
mDebugMode = Environment.MachineName.Equals("laptop-matthijs", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
private IList<Type> mTypes;
|
||||||
|
public MethodBase LoadTypeTableRef;
|
||||||
|
public MethodBase SetTypeInfoRef;
|
||||||
|
public MethodBase SetMethodInfoRef;
|
||||||
|
public FieldInfo TypesFieldRef;
|
||||||
|
public uint VTableEntrySize;
|
||||||
|
public uint ArrayTypeId;
|
||||||
|
public IList<MethodBase> Methods;
|
||||||
|
public event GetMethodIdentifierEventHandler GetMethodIdentifier;
|
||||||
|
|
||||||
|
public IList<Type> Types {
|
||||||
|
get {
|
||||||
|
return mTypes;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
mTypes = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void Push(uint aValue);
|
||||||
|
protected abstract void Push(string aLabelName);
|
||||||
|
protected abstract void Call(MethodBase aMethod);
|
||||||
|
protected abstract void Move(string aDestLabelName, int aValue);
|
||||||
|
|
||||||
|
public override void DoAssemble() {
|
||||||
|
string xTheName = DataMember.GetStaticFieldName(TypesFieldRef);
|
||||||
|
DataMember xDataMember = (from item in Assembler.DataMembers
|
||||||
|
where item.Name == xTheName
|
||||||
|
select item).FirstOrDefault();
|
||||||
|
if (xDataMember != null) {
|
||||||
|
Assembler.DataMembers.Remove((from item in Assembler.DataMembers
|
||||||
|
where item == xDataMember
|
||||||
|
select item).First());
|
||||||
|
}
|
||||||
|
var xData = new byte[16 + (mTypes.Count * VTableEntrySize)];
|
||||||
|
var xTemp = BitConverter.GetBytes(ArrayTypeId);
|
||||||
|
xTemp = BitConverter.GetBytes(0x80000002);
|
||||||
|
Array.Copy(xTemp, 0, xData, 4, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(mTypes.Count);
|
||||||
|
Array.Copy(xTemp, 0, xData, 8, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(VTableEntrySize);
|
||||||
|
Array.Copy(xTemp, 0, xData, 12, 4);
|
||||||
|
Assembler.DataMembers.Add(new DataMember(xTheName + "__Contents", xData));
|
||||||
|
Assembler.DataMembers.Add(new DataMember(xTheName, ElementReference.New(xTheName + "__Contents")));
|
||||||
|
Push((uint)mTypes.Count);
|
||||||
|
Call(LoadTypeTableRef);
|
||||||
|
for (int i = 0; i < mTypes.Count; i++) {
|
||||||
|
Type xType = mTypes[i];
|
||||||
|
// value contains true if the method is an interface method definition
|
||||||
|
SortedList<MethodBase, bool> xEmittedMethods = new SortedList<MethodBase, bool>(new MethodBaseComparer());
|
||||||
|
foreach (MethodBase xMethod in xType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
|
||||||
|
if (Methods.Contains(xMethod))//) && !xMethod.IsAbstract)
|
||||||
|
{
|
||||||
|
xEmittedMethods.Add(xMethod, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private IList<Type> mTypes;
|
foreach (MethodBase xCtor in xType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
|
||||||
public MethodBase LoadTypeTableRef;
|
if (Methods.Contains(xCtor))// && !xCtor.IsAbstract)
|
||||||
public MethodBase SetTypeInfoRef;
|
{
|
||||||
public MethodBase SetMethodInfoRef;
|
xEmittedMethods.Add(xCtor, false);
|
||||||
public FieldInfo TypesFieldRef;
|
}
|
||||||
public uint VTableEntrySize;
|
}
|
||||||
public uint ArrayTypeId;
|
foreach (var xIntf in xType.GetInterfaces()) {
|
||||||
public IList<MethodBase> Methods;
|
foreach (var xMethodIntf in xIntf.GetMethods()) {
|
||||||
public event GetMethodIdentifierEventHandler GetMethodIdentifier;
|
var xActualMethod = xType.GetMethod(xIntf.FullName + "." + xMethodIntf.Name,
|
||||||
|
(from xParam in xMethodIntf.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
|
||||||
public IList<Type> Types {
|
if (xActualMethod == null) {
|
||||||
get {
|
// get private implemenation
|
||||||
return mTypes;
|
xActualMethod = xType.GetMethod(xMethodIntf.Name,
|
||||||
}
|
(from xParam in xMethodIntf.GetParameters()
|
||||||
set {
|
select xParam.ParameterType).ToArray());
|
||||||
mTypes = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void Push(uint aValue);
|
|
||||||
protected abstract void Push(string aLabelName);
|
|
||||||
protected abstract void Call(MethodBase aMethod);
|
|
||||||
protected abstract void Move(string aDestLabelName, int aValue);
|
|
||||||
|
|
||||||
public override void DoAssemble() {
|
|
||||||
XmlWriter xDebug=null;
|
|
||||||
if (mDebugMode)
|
|
||||||
{
|
|
||||||
xDebug = XmlWriter.Create(@"d:\vtables.xml");
|
|
||||||
xDebug.WriteStartDocument();
|
|
||||||
xDebug.WriteStartElement("VTables");
|
|
||||||
xDebug.WriteStartElement("AllMethods");
|
|
||||||
for (int i = 0; i < Methods.Count; i++)
|
|
||||||
{
|
|
||||||
MethodBase xTheMethod = Methods[i];
|
|
||||||
xDebug.WriteStartElement("Method");
|
|
||||||
xDebug.WriteAttributeString("Id", GetMethodIdentifier(xTheMethod).ToString("X"));
|
|
||||||
xDebug.WriteAttributeString("Name", xTheMethod.GetFullName());
|
|
||||||
xDebug.WriteEndElement();
|
|
||||||
}
|
|
||||||
xDebug.WriteEndElement();
|
|
||||||
}
|
}
|
||||||
string xTheName = DataMember.GetStaticFieldName(TypesFieldRef);
|
if (xActualMethod == null) {
|
||||||
DataMember xDataMember = (from item in Assembler.DataMembers
|
try {
|
||||||
where item.Name == xTheName
|
var xMap = xType.GetInterfaceMap(xIntf);
|
||||||
select item).FirstOrDefault();
|
for (int k = 0; k < xMap.InterfaceMethods.Length; k++) {
|
||||||
if (xDataMember != null) {
|
if (xMap.InterfaceMethods[k] == xMethodIntf) {
|
||||||
Assembler.DataMembers.Remove((from item in Assembler.DataMembers
|
xActualMethod = xMap.TargetMethods[k];
|
||||||
where item == xDataMember
|
break;
|
||||||
select item).First());
|
}
|
||||||
}
|
|
||||||
var xData = new byte[16 + (mTypes.Count * VTableEntrySize)];
|
|
||||||
var xTemp = BitConverter.GetBytes(ArrayTypeId);
|
|
||||||
Array.Copy(xTemp, 0, xData, 0, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(0x80000002);
|
|
||||||
Array.Copy(xTemp, 0, xData, 4, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(mTypes.Count);
|
|
||||||
Array.Copy(xTemp, 0, xData, 8, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(VTableEntrySize);
|
|
||||||
Array.Copy(xTemp, 0, xData, 12, 4);
|
|
||||||
Assembler.DataMembers.Add(new DataMember(xTheName + "__Contents", xData));
|
|
||||||
Assembler.DataMembers.Add(new DataMember(xTheName, ElementReference.New(xTheName + "__Contents")));
|
|
||||||
Push((uint)mTypes.Count);
|
|
||||||
Call(LoadTypeTableRef);
|
|
||||||
for (int i = 0; i < mTypes.Count; i++) {
|
|
||||||
if (mDebugMode)
|
|
||||||
{
|
|
||||||
xDebug.WriteStartElement("Type");
|
|
||||||
xDebug.WriteAttributeString("Id", i.ToString("X"));
|
|
||||||
xDebug.WriteAttributeString("Name", MethodInfoLabelGenerator.GetFullName(mTypes[i]));
|
|
||||||
}
|
}
|
||||||
try
|
} catch {
|
||||||
{
|
}
|
||||||
Type xType = mTypes[i];
|
}
|
||||||
if(xType == typeof(ConsoleKey))
|
if (Methods.Contains(xMethodIntf)) {
|
||||||
{
|
if (!xEmittedMethods.ContainsKey(xMethodIntf)) {
|
||||||
Console.Write("");
|
xEmittedMethods.Add(xMethodIntf,
|
||||||
}
|
true);
|
||||||
// value contains true if the method is an interface method definition
|
}
|
||||||
SortedList<MethodBase, bool> xEmittedMethods = new SortedList<MethodBase, bool>(new MethodBaseComparer());
|
|
||||||
foreach (MethodBase xMethod in xType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
|
|
||||||
{
|
|
||||||
if (Methods.Contains(xMethod))//) && !xMethod.IsAbstract)
|
|
||||||
{
|
|
||||||
xEmittedMethods.Add(xMethod, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (MethodBase xCtor in xType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
|
|
||||||
{
|
|
||||||
if (Methods.Contains(xCtor))// && !xCtor.IsAbstract)
|
|
||||||
{
|
|
||||||
xEmittedMethods.Add(xCtor, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (var xIntf in xType.GetInterfaces())
|
|
||||||
{
|
|
||||||
foreach (var xMethodIntf in xIntf.GetMethods())
|
|
||||||
{
|
|
||||||
var xActualMethod = xType.GetMethod(xIntf.FullName + "." + xMethodIntf.Name,
|
|
||||||
(from xParam in xMethodIntf.GetParameters()
|
|
||||||
select xParam.ParameterType).ToArray());
|
|
||||||
|
|
||||||
if (xActualMethod == null)
|
|
||||||
{
|
|
||||||
// get private implemenation
|
|
||||||
xActualMethod = xType.GetMethod(xMethodIntf.Name,
|
|
||||||
(from xParam in xMethodIntf.GetParameters()
|
|
||||||
select xParam.ParameterType).ToArray());
|
|
||||||
} if (xActualMethod == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var xMap = xType.GetInterfaceMap(xIntf);
|
|
||||||
for (int k = 0; k < xMap.InterfaceMethods.Length; k++)
|
|
||||||
{
|
|
||||||
if (xMap.InterfaceMethods[k] == xMethodIntf)
|
|
||||||
{
|
|
||||||
xActualMethod = xMap.TargetMethods[k];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
if (Methods.Contains(xMethodIntf))
|
|
||||||
{
|
|
||||||
if (!xEmittedMethods.ContainsKey(xMethodIntf))
|
|
||||||
{
|
|
||||||
xEmittedMethods.Add(xMethodIntf,
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xType == typeof(object))
|
|
||||||
{ Console.Write(""); }
|
|
||||||
if (!xType.IsInterface)
|
|
||||||
{
|
|
||||||
Push((uint)i);
|
|
||||||
}
|
|
||||||
int? xBaseIndex = null;
|
|
||||||
if (xType.BaseType == null)
|
|
||||||
{
|
|
||||||
xBaseIndex = i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int t = 0; t < mTypes.Count; t++)
|
|
||||||
{
|
|
||||||
if (mTypes[t].ToString() == xType.BaseType.ToString())
|
|
||||||
{
|
|
||||||
xBaseIndex = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xBaseIndex == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Base type not found!");
|
|
||||||
}
|
|
||||||
if (mDebugMode)
|
|
||||||
{
|
|
||||||
xDebug.WriteAttributeString("BaseId", xBaseIndex.Value.ToString("X"));
|
|
||||||
}
|
|
||||||
for (int x = xEmittedMethods.Count - 1; x >= 0; x--) {
|
|
||||||
if (!Methods.Contains(xEmittedMethods.Keys[x])) { xEmittedMethods.RemoveAt(x); }
|
|
||||||
}
|
|
||||||
if (!xType.IsInterface)
|
|
||||||
{
|
|
||||||
//Move(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), i);
|
|
||||||
Assembler.DataMembers.Add(
|
|
||||||
new DataMember(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), new int[] {i}));
|
|
||||||
Push((uint)xBaseIndex.Value);
|
|
||||||
//Push("0" + xEmittedMethods.Count.ToString("X") + "h");
|
|
||||||
xData = new byte[16 + (xEmittedMethods.Count * 4)];
|
|
||||||
xTemp = BitConverter.GetBytes(ArrayTypeId);
|
|
||||||
Array.Copy(xTemp, 0, xData, 0, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(0x80000002); // embedded array
|
|
||||||
Array.Copy(xTemp, 0, xData, 4, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(xEmittedMethods.Count); // embedded array
|
|
||||||
Array.Copy(xTemp, 0, xData, 8, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(4); // embedded array
|
|
||||||
Array.Copy(xTemp, 0, xData, 12, 4);
|
|
||||||
string xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].AssemblyQualifiedName) + "__MethodIndexesArray";
|
|
||||||
Assembler.DataMembers.Add(new DataMember(xDataName, xData));
|
|
||||||
Push(xDataName);
|
|
||||||
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].AssemblyQualifiedName) + "__MethodAddressesArray";
|
|
||||||
Assembler.DataMembers.Add(new DataMember(xDataName, xData));
|
|
||||||
Push(xDataName);
|
|
||||||
xData = new byte[16 + Encoding.Unicode.GetByteCount(mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.GetName().FullName)];
|
|
||||||
xTemp = BitConverter.GetBytes(ArrayTypeId);
|
|
||||||
Array.Copy(xTemp, 0, xData, 0, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(0x80000002); // embedded array
|
|
||||||
Array.Copy(xTemp, 0, xData, 4, 4);
|
|
||||||
xTemp = BitConverter.GetBytes((mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.GetName().FullName).Length);
|
|
||||||
Array.Copy(xTemp, 0, xData, 8, 4);
|
|
||||||
xTemp = BitConverter.GetBytes(2); // embedded array
|
|
||||||
Array.Copy(xTemp, 0, xData, 12, 4);
|
|
||||||
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(MethodInfoLabelGenerator.GetFullName(mTypes[i]));
|
|
||||||
mAssembler.DataMembers.Add(new DataMember(xDataName, xData));
|
|
||||||
Push((uint)xEmittedMethods.Count);
|
|
||||||
//Push("0");
|
|
||||||
Call(SetTypeInfoRef);
|
|
||||||
}
|
|
||||||
for (int j = 0; j < xEmittedMethods.Count; j++)
|
|
||||||
{
|
|
||||||
MethodBase xMethod = xEmittedMethods.Keys[j];
|
|
||||||
var xMethodId = GetMethodIdentifier(xMethod);
|
|
||||||
if (mDebugMode)
|
|
||||||
{
|
|
||||||
xDebug.WriteStartElement("Method");
|
|
||||||
xDebug.WriteAttributeString("Id", xMethodId.ToString("X"));
|
|
||||||
xDebug.WriteAttributeString("Name", xMethod.GetFullName());
|
|
||||||
xDebug.WriteEndElement();
|
|
||||||
}
|
|
||||||
if (!xType.IsInterface)
|
|
||||||
{
|
|
||||||
if (xEmittedMethods.Values[j])
|
|
||||||
{
|
|
||||||
var xNewMethod = xType.GetMethod(xMethod.DeclaringType.FullName + "." + xMethod.Name,
|
|
||||||
(from xParam in xMethod.GetParameters()
|
|
||||||
select xParam.ParameterType).ToArray());
|
|
||||||
|
|
||||||
if (xNewMethod == null)
|
|
||||||
{
|
|
||||||
// get private implemenation
|
|
||||||
xNewMethod = xType.GetMethod(xMethod.Name,
|
|
||||||
(from xParam in xMethod.GetParameters()
|
|
||||||
select xParam.ParameterType).ToArray());
|
|
||||||
}
|
|
||||||
if (xNewMethod == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var xMap = xType.GetInterfaceMap(xMethod.DeclaringType);
|
|
||||||
for (int k = 0; k < xMap.InterfaceMethods.Length; k++)
|
|
||||||
{
|
|
||||||
if (xMap.InterfaceMethods[k] == xMethod)
|
|
||||||
{
|
|
||||||
xNewMethod = xMap.TargetMethods[k];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
if (xNewMethod == null) { System.Diagnostics.Debugger.Break(); }
|
|
||||||
xMethod = xNewMethod;
|
|
||||||
}
|
|
||||||
//Move(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod), xMethodId);
|
|
||||||
Assembler.DataMembers.Add(
|
|
||||||
new DataMember(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod),
|
|
||||||
new int[] {xMethodId}));
|
|
||||||
|
|
||||||
Push((uint)i);
|
|
||||||
Push((uint)j);
|
|
||||||
|
|
||||||
Push((uint)xMethodId);
|
|
||||||
if (xMethod.IsAbstract)
|
|
||||||
{
|
|
||||||
// abstract methods dont have bodies, oiw, are not emitted
|
|
||||||
Push(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var xTest = GetService<IMetaDataInfoService>().GetMethodInfo(xMethod, false);
|
|
||||||
Push(xTest.LabelName);
|
|
||||||
}
|
|
||||||
//xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0";
|
|
||||||
//xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod));
|
|
||||||
//mAssembler.DataMembers.Add(new DataMember(xDataName, "db", xDataValue));
|
|
||||||
//Push(xDataName);
|
|
||||||
Push(0);
|
|
||||||
Call(SetMethodInfoRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (mDebugMode)
|
|
||||||
{
|
|
||||||
xDebug.WriteEndElement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mDebugMode)
|
|
||||||
{
|
|
||||||
xDebug.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!xType.IsInterface) {
|
||||||
|
Push((uint)i);
|
||||||
|
}
|
||||||
|
int? xBaseIndex = null;
|
||||||
|
if (xType.BaseType == null) {
|
||||||
|
xBaseIndex = i;
|
||||||
|
} else {
|
||||||
|
for (int t = 0; t < mTypes.Count; t++) {
|
||||||
|
if (mTypes[t].ToString() == xType.BaseType.ToString()) {
|
||||||
|
xBaseIndex = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xBaseIndex == null) {
|
||||||
|
throw new Exception("Base type not found!");
|
||||||
|
}
|
||||||
|
for (int x = xEmittedMethods.Count - 1; x >= 0; x--) {
|
||||||
|
if (!Methods.Contains(xEmittedMethods.Keys[x])) {
|
||||||
|
xEmittedMethods.RemoveAt(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!xType.IsInterface) {
|
||||||
|
//Move(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), i);
|
||||||
|
Assembler.DataMembers.Add(
|
||||||
|
new DataMember(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), new int[] { i }));
|
||||||
|
Push((uint)xBaseIndex.Value);
|
||||||
|
//Push("0" + xEmittedMethods.Count.ToString("X") + "h");
|
||||||
|
xData = new byte[16 + (xEmittedMethods.Count * 4)];
|
||||||
|
xTemp = BitConverter.GetBytes(ArrayTypeId);
|
||||||
|
Array.Copy(xTemp, 0, xData, 0, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(0x80000002); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 4, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(xEmittedMethods.Count); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 8, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(4); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 12, 4);
|
||||||
|
string xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].AssemblyQualifiedName) + "__MethodIndexesArray";
|
||||||
|
Assembler.DataMembers.Add(new DataMember(xDataName, xData));
|
||||||
|
Push(xDataName);
|
||||||
|
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].AssemblyQualifiedName) + "__MethodAddressesArray";
|
||||||
|
Assembler.DataMembers.Add(new DataMember(xDataName, xData));
|
||||||
|
Push(xDataName);
|
||||||
|
xData = new byte[16 + Encoding.Unicode.GetByteCount(mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.GetName().FullName)];
|
||||||
|
xTemp = BitConverter.GetBytes(ArrayTypeId);
|
||||||
|
Array.Copy(xTemp, 0, xData, 0, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(0x80000002); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 4, 4);
|
||||||
|
xTemp = BitConverter.GetBytes((mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.GetName().FullName).Length);
|
||||||
|
Array.Copy(xTemp, 0, xData, 8, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(2); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 12, 4);
|
||||||
|
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(MethodInfoLabelGenerator.GetFullName(mTypes[i]));
|
||||||
|
mAssembler.DataMembers.Add(new DataMember(xDataName, xData));
|
||||||
|
Push((uint)xEmittedMethods.Count);
|
||||||
|
//Push("0");
|
||||||
|
Call(SetTypeInfoRef);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < xEmittedMethods.Count; j++) {
|
||||||
|
MethodBase xMethod = xEmittedMethods.Keys[j];
|
||||||
|
var xMethodId = GetMethodIdentifier(xMethod);
|
||||||
|
if (!xType.IsInterface) {
|
||||||
|
if (xEmittedMethods.Values[j]) {
|
||||||
|
var xNewMethod = xType.GetMethod(xMethod.DeclaringType.FullName + "." + xMethod.Name,
|
||||||
|
(from xParam in xMethod.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
|
||||||
|
if (xNewMethod == null) {
|
||||||
|
// get private implemenation
|
||||||
|
xNewMethod = xType.GetMethod(xMethod.Name,
|
||||||
|
(from xParam in xMethod.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
}
|
||||||
|
if (xNewMethod == null) {
|
||||||
|
try {
|
||||||
|
var xMap = xType.GetInterfaceMap(xMethod.DeclaringType);
|
||||||
|
for (int k = 0; k < xMap.InterfaceMethods.Length; k++) {
|
||||||
|
if (xMap.InterfaceMethods[k] == xMethod) {
|
||||||
|
xNewMethod = xMap.TargetMethods[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xMethod = xNewMethod;
|
||||||
|
}
|
||||||
|
//Move(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod), xMethodId);
|
||||||
|
Assembler.DataMembers.Add(
|
||||||
|
new DataMember(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod),
|
||||||
|
new int[] { xMethodId }));
|
||||||
|
|
||||||
|
Push((uint)i);
|
||||||
|
Push((uint)j);
|
||||||
|
|
||||||
|
Push((uint)xMethodId);
|
||||||
|
if (xMethod.IsAbstract) {
|
||||||
|
// abstract methods dont have bodies, oiw, are not emitted
|
||||||
|
Push(0);
|
||||||
|
} else {
|
||||||
|
var xTest = GetService<IMetaDataInfoService>().GetMethodInfo(xMethod, false);
|
||||||
|
Push(xTest.LabelName);
|
||||||
|
}
|
||||||
|
//xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0";
|
||||||
|
//xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod));
|
||||||
|
//mAssembler.DataMembers.Add(new DataMember(xDataName, "db", xDataValue));
|
||||||
|
//Push(xDataName);
|
||||||
|
Push(0);
|
||||||
|
Call(SetMethodInfoRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,26 @@ namespace Cosmos.IL2CPU.Profiler {
|
||||||
protected override void MethodEnd(MethodInfo aMethod) {
|
protected override void MethodEnd(MethodInfo aMethod) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void Push(uint aValue) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Push(string aLabelName) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Call(System.Reflection.MethodBase aMethod) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Move(string aDestLabelName, int aValue) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int GetVTableEntrySize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,5 +165,35 @@ namespace Cosmos.IL2CPU.X86 {
|
||||||
aOutput.WriteLine("org 0x200000");
|
aOutput.WriteLine("org 0x200000");
|
||||||
base.FlushText(aOutput);
|
base.FlushText(aOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Move(string aDestLabelName, int aValue) {
|
||||||
|
new Move {
|
||||||
|
DestinationRef = ElementReference.New(aDestLabelName),
|
||||||
|
DestinationIsIndirect = true,
|
||||||
|
SourceValue = (uint)aValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Push(uint aValue) {
|
||||||
|
new Push {
|
||||||
|
DestinationValue = aValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Push(string aLabelName) {
|
||||||
|
new Push {
|
||||||
|
DestinationRef = ElementReference.New(aLabelName)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Call(MethodBase aMethod) {
|
||||||
|
new IL2CPU.X86.Call {
|
||||||
|
DestinationLabel = CPU.MethodInfoLabelGenerator.GenerateLabelName(aMethod)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int GetVTableEntrySize() {
|
||||||
|
return 16; // todo: retrieve from actual type info
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
||||||
//select item ).Count();
|
//select item ).Count();
|
||||||
int xGCFieldCount = xType.GetFields().Count( x => x.FieldType.IsValueType );
|
int xGCFieldCount = xType.GetFields().Count( x => x.FieldType.IsValueType );
|
||||||
|
|
||||||
|
// todo: use a cleaner approach here. this class shouldnt assemble the string
|
||||||
string strTypeId = "VMT__TYPE_ID_HOLDER__" + xMethod.Value.DeclaringType.FullName;
|
string strTypeId = "VMT__TYPE_ID_HOLDER__" + xMethod.Value.DeclaringType.FullName;
|
||||||
|
|
||||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ using System.Reflection.Emit;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Indy.IL2CPU;
|
||||||
|
using Indy.IL2CPU.IL;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU {
|
namespace Cosmos.IL2CPU {
|
||||||
|
|
||||||
|
|
@ -22,11 +25,15 @@ namespace Cosmos.IL2CPU {
|
||||||
private System.IO.TextWriter mLog;
|
private System.IO.TextWriter mLog;
|
||||||
#region Properties
|
#region Properties
|
||||||
public List<DataMember> DataMembers {
|
public List<DataMember> DataMembers {
|
||||||
get { return mDataMembers; }
|
get {
|
||||||
|
return mDataMembers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Instruction> Instructions {
|
public List<Instruction> Instructions {
|
||||||
get { return mInstructions; }
|
get {
|
||||||
|
return mInstructions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public static Assembler CurrentInstance {
|
public static Assembler CurrentInstance {
|
||||||
get {
|
get {
|
||||||
|
|
@ -109,7 +116,6 @@ namespace Cosmos.IL2CPU {
|
||||||
new Comment(this, "---------------------------------------------------------");
|
new Comment(this, "---------------------------------------------------------");
|
||||||
new Comment(this, "Type: " + aMethod.MethodBase.DeclaringType.ToString());
|
new Comment(this, "Type: " + aMethod.MethodBase.DeclaringType.ToString());
|
||||||
new Comment(this, "Name: " + aMethod.MethodBase.Name);
|
new Comment(this, "Name: " + aMethod.MethodBase.Name);
|
||||||
new Comment(this, aMethod.Type.ToString());
|
|
||||||
new Comment(this, "Plugged: " + (aMethod.PlugMethod == null ? "No" : "Yes"));
|
new Comment(this, "Plugged: " + (aMethod.PlugMethod == null ? "No" : "Yes"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,13 +149,14 @@ namespace Cosmos.IL2CPU {
|
||||||
} else {
|
} else {
|
||||||
xILOp = mILOpsHi[xOpCodeVal & 0xFF];
|
xILOp = mILOpsHi[xOpCodeVal & 0xFF];
|
||||||
}
|
}
|
||||||
mLog.WriteLine ( "\t[" + xILOp.ToString() + "] \t Stack start: " + Stack.Count.ToString() );
|
//mLog.WriteLine ( "\t[" + xILOp.ToString() + "] \t Stack start: " + Stack.Count.ToString() );
|
||||||
|
mLog.WriteLine("\t{0} {1}", Stack.Count, xILOp.GetType().Name);
|
||||||
mLog.Flush();
|
mLog.Flush();
|
||||||
new Comment(this, "[" + xILOp.ToString() + "]");
|
new Comment(this, "[" + xILOp.ToString() + "]");
|
||||||
BeforeOp(aMethod, xOpCode);
|
BeforeOp(aMethod, xOpCode);
|
||||||
xILOp.Execute(aMethod, xOpCode);
|
xILOp.Execute(aMethod, xOpCode);
|
||||||
AfterOp(aMethod, xOpCode);
|
AfterOp(aMethod, xOpCode);
|
||||||
mLog.WriteLine( " end: " + Stack.Count.ToString() );
|
//mLog.WriteLine( " end: " + Stack.Count.ToString() );
|
||||||
|
|
||||||
}
|
}
|
||||||
MethodEnd(aMethod);
|
MethodEnd(aMethod);
|
||||||
|
|
@ -257,5 +264,205 @@ namespace Cosmos.IL2CPU {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void Push(uint aValue);
|
||||||
|
protected abstract void Push(string aLabelName);
|
||||||
|
protected abstract void Call(MethodBase aMethod);
|
||||||
|
protected abstract void Move(string aDestLabelName, int aValue);
|
||||||
|
protected abstract int GetVTableEntrySize();
|
||||||
|
|
||||||
|
private void GenerateVMTCode(IList<Type> aTypes, IList<MethodBase> aMethods) {
|
||||||
|
// initialization
|
||||||
|
var xSetTypeInfoRef = VTablesImplRefs.SetTypeInfoRef;
|
||||||
|
var xSetMethodInfoRef = VTablesImplRefs.SetMethodInfoRef;
|
||||||
|
var xLoadTypeTableRef = VTablesImplRefs.LoadTypeTableRef;
|
||||||
|
var xTypesFieldRef = VTablesImplRefs.VTablesImplDef.GetField("mTypes",
|
||||||
|
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
|
||||||
|
// data we need but dont have:
|
||||||
|
|
||||||
|
// end initialization
|
||||||
|
string xTheName = DataMember.GetStaticFieldName(xTypesFieldRef);
|
||||||
|
DataMember xDataMember = (from item in Assembler.mCurrentInstance.DataMembers
|
||||||
|
where item.Name == xTheName
|
||||||
|
select item).FirstOrDefault();
|
||||||
|
if (xDataMember != null) {
|
||||||
|
Assembler.mCurrentInstance.DataMembers.Remove((from item in Assembler.mCurrentInstance.DataMembers
|
||||||
|
where item == xDataMember
|
||||||
|
select item).First());
|
||||||
|
}
|
||||||
|
var xData = new byte[16 + (aTypes.Count * GetVTableEntrySize())];
|
||||||
|
var xTemp = BitConverter.GetBytes(aTypes.IndexOf(typeof(Array)));
|
||||||
|
xTemp = BitConverter.GetBytes(0x80000002);
|
||||||
|
Array.Copy(xTemp, 0, xData, 4, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(aTypes.Count);
|
||||||
|
Array.Copy(xTemp, 0, xData, 8, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(GetVTableEntrySize());
|
||||||
|
Array.Copy(xTemp, 0, xData, 12, 4);
|
||||||
|
Assembler.mCurrentInstance.DataMembers.Add(new DataMember(xTheName + "__Contents", xData));
|
||||||
|
Assembler.mCurrentInstance.DataMembers.Add(new DataMember(xTheName, ElementReference.New(xTheName + "__Contents")));
|
||||||
|
Push((uint)aTypes.Count);
|
||||||
|
Call(xLoadTypeTableRef);
|
||||||
|
for (int i = 0; i < aTypes.Count; i++) {
|
||||||
|
Type xType = aTypes[i];
|
||||||
|
// value contains true if the method is an interface method definition
|
||||||
|
SortedList<MethodBase, bool> xEmittedMethods = new SortedList<MethodBase, bool>(new MethodBaseComparer());
|
||||||
|
foreach (MethodBase xMethod in xType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
|
||||||
|
if (aMethods.Contains(xMethod))//) && !xMethod.IsAbstract)
|
||||||
|
{
|
||||||
|
xEmittedMethods.Add(xMethod, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (MethodBase xCtor in xType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
|
||||||
|
if (aMethods.Contains(xCtor))// && !xCtor.IsAbstract)
|
||||||
|
{
|
||||||
|
xEmittedMethods.Add(xCtor, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var xIntf in xType.GetInterfaces()) {
|
||||||
|
foreach (var xMethodIntf in xIntf.GetMethods()) {
|
||||||
|
var xActualMethod = xType.GetMethod(xIntf.FullName + "." + xMethodIntf.Name,
|
||||||
|
(from xParam in xMethodIntf.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
|
||||||
|
if (xActualMethod == null) {
|
||||||
|
// get private implemenation
|
||||||
|
xActualMethod = xType.GetMethod(xMethodIntf.Name,
|
||||||
|
(from xParam in xMethodIntf.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
}
|
||||||
|
if (xActualMethod == null) {
|
||||||
|
try {
|
||||||
|
var xMap = xType.GetInterfaceMap(xIntf);
|
||||||
|
for (int k = 0; k < xMap.InterfaceMethods.Length; k++) {
|
||||||
|
if (xMap.InterfaceMethods[k] == xMethodIntf) {
|
||||||
|
xActualMethod = xMap.TargetMethods[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aMethods.Contains(xMethodIntf)) {
|
||||||
|
if (!xEmittedMethods.ContainsKey(xMethodIntf)) {
|
||||||
|
xEmittedMethods.Add(xMethodIntf,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!xType.IsInterface) {
|
||||||
|
Push((uint)i);
|
||||||
|
}
|
||||||
|
int? xBaseIndex = null;
|
||||||
|
if (xType.BaseType == null) {
|
||||||
|
xBaseIndex = i;
|
||||||
|
} else {
|
||||||
|
for (int t = 0; t < aTypes.Count; t++) {
|
||||||
|
// todo: optimize check
|
||||||
|
if (aTypes[t].ToString() == xType.BaseType.ToString()) {
|
||||||
|
xBaseIndex = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xBaseIndex == null) {
|
||||||
|
throw new Exception("Base type not found!");
|
||||||
|
}
|
||||||
|
for (int x = xEmittedMethods.Count - 1; x >= 0; x--) {
|
||||||
|
if (!aMethods.Contains(xEmittedMethods.Keys[x])) {
|
||||||
|
xEmittedMethods.RemoveAt(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!xType.IsInterface) {
|
||||||
|
//Move(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), i);
|
||||||
|
Assembler.mCurrentInstance.DataMembers.Add(
|
||||||
|
new DataMember("VMT__TYPE_ID_HOLDER__" + xType.FullName, new int[] { i }));
|
||||||
|
Push((uint)xBaseIndex.Value);
|
||||||
|
//Push("0" + xEmittedMethods.Count.ToString("X") + "h");
|
||||||
|
xData = new byte[16 + (xEmittedMethods.Count * 4)];
|
||||||
|
xTemp = BitConverter.GetBytes(aTypes.IndexOf(typeof(Array)));
|
||||||
|
Array.Copy(xTemp, 0, xData, 0, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(0x80000002); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 4, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(xEmittedMethods.Count); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 8, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(4); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 12, 4);
|
||||||
|
string xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(aTypes[i].AssemblyQualifiedName) + "__MethodIndexesArray";
|
||||||
|
Assembler.mCurrentInstance.DataMembers.Add(new DataMember(xDataName, xData));
|
||||||
|
Push(xDataName);
|
||||||
|
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(aTypes[i].AssemblyQualifiedName) + "__MethodAddressesArray";
|
||||||
|
Assembler.mCurrentInstance.DataMembers.Add(new DataMember(xDataName, xData));
|
||||||
|
Push(xDataName);
|
||||||
|
xData = new byte[16 + Encoding.Unicode.GetByteCount(aTypes[i].FullName + ", " + aTypes[i].Module.Assembly.GetName().FullName)];
|
||||||
|
xTemp = BitConverter.GetBytes(aTypes.IndexOf(typeof(Array)));
|
||||||
|
Array.Copy(xTemp, 0, xData, 0, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(0x80000002); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 4, 4);
|
||||||
|
xTemp = BitConverter.GetBytes((aTypes[i].FullName + ", " + aTypes[i].Module.Assembly.GetName().FullName).Length);
|
||||||
|
Array.Copy(xTemp, 0, xData, 8, 4);
|
||||||
|
xTemp = BitConverter.GetBytes(2); // embedded array
|
||||||
|
Array.Copy(xTemp, 0, xData, 12, 4);
|
||||||
|
xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(MethodInfoLabelGenerator.GetFullName(aTypes[i]));
|
||||||
|
Assembler.CurrentInstance.DataMembers.Add(new DataMember(xDataName, xData));
|
||||||
|
Push((uint)xEmittedMethods.Count);
|
||||||
|
//Push("0");
|
||||||
|
Call(xSetTypeInfoRef);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < xEmittedMethods.Count; j++) {
|
||||||
|
MethodBase xMethod = xEmittedMethods.Keys[j];
|
||||||
|
var xMethodId = aMethods.IndexOf(xMethod);
|
||||||
|
if (!xType.IsInterface) {
|
||||||
|
if (xEmittedMethods.Values[j]) {
|
||||||
|
var xNewMethod = xType.GetMethod(xMethod.DeclaringType.FullName + "." + xMethod.Name,
|
||||||
|
(from xParam in xMethod.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
|
||||||
|
if (xNewMethod == null) {
|
||||||
|
// get private implemenation
|
||||||
|
xNewMethod = xType.GetMethod(xMethod.Name,
|
||||||
|
(from xParam in xMethod.GetParameters()
|
||||||
|
select xParam.ParameterType).ToArray());
|
||||||
|
}
|
||||||
|
if (xNewMethod == null) {
|
||||||
|
try {
|
||||||
|
var xMap = xType.GetInterfaceMap(xMethod.DeclaringType);
|
||||||
|
for (int k = 0; k < xMap.InterfaceMethods.Length; k++) {
|
||||||
|
if (xMap.InterfaceMethods[k] == xMethod) {
|
||||||
|
xNewMethod = xMap.TargetMethods[k];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xMethod = xNewMethod;
|
||||||
|
}
|
||||||
|
//Move(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod), xMethodId);
|
||||||
|
//Assembler.DataMembers.Add(
|
||||||
|
// new DataMember(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod),
|
||||||
|
// new int[] { xMethodId }));
|
||||||
|
|
||||||
|
Push((uint)i);
|
||||||
|
Push((uint)j);
|
||||||
|
|
||||||
|
Push((uint)xMethodId);
|
||||||
|
if (xMethod.IsAbstract) {
|
||||||
|
// abstract methods dont have bodies, oiw, are not emitted
|
||||||
|
Push(0);
|
||||||
|
} else {
|
||||||
|
//var xTest = GetService<IMetaDataInfoService>().GetMethodInfo(xMethod, false);
|
||||||
|
//Push(xTest.LabelName);
|
||||||
|
}
|
||||||
|
//xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0";
|
||||||
|
//xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod));
|
||||||
|
//mAssembler.DataMembers.Add(new DataMember(xDataName, "db", xDataValue));
|
||||||
|
//Push(xDataName);
|
||||||
|
Push(0);
|
||||||
|
//Call(SetMethodInfoRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -198,6 +198,8 @@ namespace Cosmos.IL2CPU {
|
||||||
}
|
}
|
||||||
//TODO: Look for Field plugs
|
//TODO: Look for Field plugs
|
||||||
}
|
}
|
||||||
|
// register any "system" types:
|
||||||
|
QueueType(typeof(Array));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecuteInternal( ( System.Reflection.MethodInfo )RuntimeEngineRefs.InitializeApplicationRef, true );
|
ExecuteInternal( ( System.Reflection.MethodInfo )RuntimeEngineRefs.InitializeApplicationRef, true );
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue