This commit is contained in:
kudzu_cp 2009-09-09 18:40:49 +00:00
parent feffd92821
commit 1d146df185
7 changed files with 496 additions and 323 deletions

View file

@ -8,22 +8,18 @@ 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 #endregion
public bool Equals(MethodBase x, MethodBase y) public bool Equals(MethodBase x, MethodBase y) {
{
return Compare(x, y) == 0; return Compare(x, y) == 0;
} }
public int GetHashCode(MethodBase obj) public int GetHashCode(MethodBase obj) {
{
return obj.GetFullName().GetHashCode(); return obj.GetFullName().GetHashCode();
} }
} }
@ -62,23 +58,6 @@ namespace Indy.IL2CPU.IL {
protected abstract void Move(string aDestLabelName, int aValue); protected abstract void Move(string aDestLabelName, int aValue);
public override void DoAssemble() { 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); string xTheName = DataMember.GetStaticFieldName(TypesFieldRef);
DataMember xDataMember = (from item in Assembler.DataMembers DataMember xDataMember = (from item in Assembler.DataMembers
where item.Name == xTheName where item.Name == xTheName
@ -90,7 +69,6 @@ namespace Indy.IL2CPU.IL {
} }
var xData = new byte[16 + (mTypes.Count * VTableEntrySize)]; var xData = new byte[16 + (mTypes.Count * VTableEntrySize)];
var xTemp = BitConverter.GetBytes(ArrayTypeId); var xTemp = BitConverter.GetBytes(ArrayTypeId);
Array.Copy(xTemp, 0, xData, 0, 4);
xTemp = BitConverter.GetBytes(0x80000002); xTemp = BitConverter.GetBytes(0x80000002);
Array.Copy(xTemp, 0, xData, 4, 4); Array.Copy(xTemp, 0, xData, 4, 4);
xTemp = BitConverter.GetBytes(mTypes.Count); xTemp = BitConverter.GetBytes(mTypes.Count);
@ -102,69 +80,47 @@ namespace Indy.IL2CPU.IL {
Push((uint)mTypes.Count); Push((uint)mTypes.Count);
Call(LoadTypeTableRef); Call(LoadTypeTableRef);
for (int i = 0; i < mTypes.Count; i++) { 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
{
Type xType = mTypes[i]; Type xType = mTypes[i];
if(xType == typeof(ConsoleKey))
{
Console.Write("");
}
// value contains true if the method is an interface method definition // value contains true if the method is an interface method definition
SortedList<MethodBase, bool> xEmittedMethods = new SortedList<MethodBase, bool>(new MethodBaseComparer()); SortedList<MethodBase, bool> xEmittedMethods = new SortedList<MethodBase, bool>(new MethodBaseComparer());
foreach (MethodBase xMethod in xType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) foreach (MethodBase xMethod in xType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
{
if (Methods.Contains(xMethod))//) && !xMethod.IsAbstract) if (Methods.Contains(xMethod))//) && !xMethod.IsAbstract)
{ {
xEmittedMethods.Add(xMethod, false); xEmittedMethods.Add(xMethod, false);
} }
} }
foreach (MethodBase xCtor in xType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) foreach (MethodBase xCtor in xType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
{
if (Methods.Contains(xCtor))// && !xCtor.IsAbstract) if (Methods.Contains(xCtor))// && !xCtor.IsAbstract)
{ {
xEmittedMethods.Add(xCtor, false); xEmittedMethods.Add(xCtor, false);
} }
} }
foreach (var xIntf in xType.GetInterfaces()) foreach (var xIntf in xType.GetInterfaces()) {
{ foreach (var xMethodIntf in xIntf.GetMethods()) {
foreach (var xMethodIntf in xIntf.GetMethods())
{
var xActualMethod = xType.GetMethod(xIntf.FullName + "." + xMethodIntf.Name, var xActualMethod = xType.GetMethod(xIntf.FullName + "." + xMethodIntf.Name,
(from xParam in xMethodIntf.GetParameters() (from xParam in xMethodIntf.GetParameters()
select xParam.ParameterType).ToArray()); select xParam.ParameterType).ToArray());
if (xActualMethod == null) if (xActualMethod == null) {
{
// get private implemenation // get private implemenation
xActualMethod = xType.GetMethod(xMethodIntf.Name, xActualMethod = xType.GetMethod(xMethodIntf.Name,
(from xParam in xMethodIntf.GetParameters() (from xParam in xMethodIntf.GetParameters()
select xParam.ParameterType).ToArray()); select xParam.ParameterType).ToArray());
} if (xActualMethod == null) }
{ if (xActualMethod == null) {
try try {
{
var xMap = xType.GetInterfaceMap(xIntf); var xMap = xType.GetInterfaceMap(xIntf);
for (int k = 0; k < xMap.InterfaceMethods.Length; k++) for (int k = 0; k < xMap.InterfaceMethods.Length; k++) {
{ if (xMap.InterfaceMethods[k] == xMethodIntf) {
if (xMap.InterfaceMethods[k] == xMethodIntf)
{
xActualMethod = xMap.TargetMethods[k]; xActualMethod = xMap.TargetMethods[k];
break; break;
} }
} }
} catch {
} }
catch { }
} }
if (Methods.Contains(xMethodIntf)) if (Methods.Contains(xMethodIntf)) {
{ if (!xEmittedMethods.ContainsKey(xMethodIntf)) {
if (!xEmittedMethods.ContainsKey(xMethodIntf))
{
xEmittedMethods.Add(xMethodIntf, xEmittedMethods.Add(xMethodIntf,
true); true);
} }
@ -172,41 +128,29 @@ namespace Indy.IL2CPU.IL {
} }
} }
if (xType == typeof(object)) if (!xType.IsInterface) {
{ Console.Write(""); }
if (!xType.IsInterface)
{
Push((uint)i); Push((uint)i);
} }
int? xBaseIndex = null; int? xBaseIndex = null;
if (xType.BaseType == null) if (xType.BaseType == null) {
{
xBaseIndex = i; xBaseIndex = i;
} } else {
else for (int t = 0; t < mTypes.Count; t++) {
{ if (mTypes[t].ToString() == xType.BaseType.ToString()) {
for (int t = 0; t < mTypes.Count; t++)
{
if (mTypes[t].ToString() == xType.BaseType.ToString())
{
xBaseIndex = t; xBaseIndex = t;
break; break;
} }
} }
} }
if (xBaseIndex == null) if (xBaseIndex == null) {
{
throw new Exception("Base type not found!"); 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--) { for (int x = xEmittedMethods.Count - 1; x >= 0; x--) {
if (!Methods.Contains(xEmittedMethods.Keys[x])) { xEmittedMethods.RemoveAt(x); } if (!Methods.Contains(xEmittedMethods.Keys[x])) {
xEmittedMethods.RemoveAt(x);
} }
if (!xType.IsInterface) }
{ if (!xType.IsInterface) {
//Move(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), i); //Move(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), i);
Assembler.DataMembers.Add( Assembler.DataMembers.Add(
new DataMember(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), new int[] { i })); new DataMember(GetService<IMetaDataInfoService>().GetTypeIdLabel(xType), new int[] { i }));
@ -242,49 +186,33 @@ namespace Indy.IL2CPU.IL {
//Push("0"); //Push("0");
Call(SetTypeInfoRef); Call(SetTypeInfoRef);
} }
for (int j = 0; j < xEmittedMethods.Count; j++) for (int j = 0; j < xEmittedMethods.Count; j++) {
{
MethodBase xMethod = xEmittedMethods.Keys[j]; MethodBase xMethod = xEmittedMethods.Keys[j];
var xMethodId = GetMethodIdentifier(xMethod); var xMethodId = GetMethodIdentifier(xMethod);
if (mDebugMode) if (!xType.IsInterface) {
{ if (xEmittedMethods.Values[j]) {
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, var xNewMethod = xType.GetMethod(xMethod.DeclaringType.FullName + "." + xMethod.Name,
(from xParam in xMethod.GetParameters() (from xParam in xMethod.GetParameters()
select xParam.ParameterType).ToArray()); select xParam.ParameterType).ToArray());
if (xNewMethod == null) if (xNewMethod == null) {
{
// get private implemenation // get private implemenation
xNewMethod = xType.GetMethod(xMethod.Name, xNewMethod = xType.GetMethod(xMethod.Name,
(from xParam in xMethod.GetParameters() (from xParam in xMethod.GetParameters()
select xParam.ParameterType).ToArray()); select xParam.ParameterType).ToArray());
} }
if (xNewMethod == null) if (xNewMethod == null) {
{ try {
try
{
var xMap = xType.GetInterfaceMap(xMethod.DeclaringType); var xMap = xType.GetInterfaceMap(xMethod.DeclaringType);
for (int k = 0; k < xMap.InterfaceMethods.Length; k++) for (int k = 0; k < xMap.InterfaceMethods.Length; k++) {
{ if (xMap.InterfaceMethods[k] == xMethod) {
if (xMap.InterfaceMethods[k] == xMethod)
{
xNewMethod = xMap.TargetMethods[k]; xNewMethod = xMap.TargetMethods[k];
break; break;
} }
} }
} catch {
} }
catch { }
} }
if (xNewMethod == null) { System.Diagnostics.Debugger.Break(); }
xMethod = xNewMethod; xMethod = xNewMethod;
} }
//Move(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod), xMethodId); //Move(GetService<IMetaDataInfoService>().GetMethodIdLabel(xMethod), xMethodId);
@ -296,13 +224,10 @@ namespace Indy.IL2CPU.IL {
Push((uint)j); Push((uint)j);
Push((uint)xMethodId); Push((uint)xMethodId);
if (xMethod.IsAbstract) if (xMethod.IsAbstract) {
{
// abstract methods dont have bodies, oiw, are not emitted // abstract methods dont have bodies, oiw, are not emitted
Push(0); Push(0);
} } else {
else
{
var xTest = GetService<IMetaDataInfoService>().GetMethodInfo(xMethod, false); var xTest = GetService<IMetaDataInfoService>().GetMethodInfo(xMethod, false);
Push(xTest.LabelName); Push(xTest.LabelName);
} }
@ -315,19 +240,6 @@ namespace Indy.IL2CPU.IL {
} }
} }
} }
finally
{
if (mDebugMode)
{
xDebug.WriteEndElement();
}
}
}
if (mDebugMode)
{
xDebug.Close();
}
} }
} }
} }

View file

@ -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;
}
} }
} }

View file

@ -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
}
} }
} }

View file

@ -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 };

View file

@ -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);
}
}
}
}
} }
} }

View file

@ -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 );