Enumerations for now. on arrays they work, List<T> not yet

This commit is contained in:
mterwoord_cp 2008-05-09 14:48:15 +00:00
parent 3060b02e0c
commit 8cab5bc18c
7 changed files with 180 additions and 87 deletions

View file

@ -7,7 +7,7 @@ using System.Text;
namespace Indy.IL2CPU.Assembler.X86 {
public class Assembler : Indy.IL2CPU.Assembler.Assembler {
public const string BreakMethodName = "_CODE_REQUESTED_BREAK_";
public const string BreakMethodName = "DebugStub_Break";
protected byte mComNumber = 0;
protected UInt16[] mComPortAddresses = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
@ -79,8 +79,6 @@ namespace Indy.IL2CPU.Assembler.X86 {
aOutputWriter.WriteLine(" hlt");
aOutputWriter.WriteLine(" jmp .loop");
aOutputWriter.WriteLine(" ");
aOutputWriter.WriteLine(" " + BreakMethodName + ":");
aOutputWriter.WriteLine(" ret");
if (mComNumber > 0) {
var xStub = new DebugStub();
xStub.Main(mComPortAddresses[mComNumber - 1]);

View file

@ -18,6 +18,16 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
}
}
public static int GetUpperBound(Array aThis, int aDimension) {
return GetLength(aThis, aDimension) - 1;
}
public static int GetLength(Array aThis, int aDimension)
{
if (aDimension != 0) { throw new NotSupportedException("Multidimensional array's are not yet supported!"); }
return aThis.Length;
}
[PlugMethod(Signature = "System_Boolean__System_Array_TrySZBinarySearch_System_Array__System_Int32__System_Int32__System_Object__System_Int32__")]
public static unsafe bool TrySZBinarySearch(uint* aArray, uint sourceIndex, uint count, uint value, out uint retVal) {
@ -68,10 +78,10 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
if (aDimension != 0) {
throw new NotSupportedException("Multidimensional arrays not supported yet!");
}
return get_Length(aThis);
return 0;
}
[PlugMethod(Signature = "System_Object__System_Array_GetValue_System_Int32_")]
[PlugMethod(Signature = "System_Object__System_Array_GetValue_System_Int32_")]
public static unsafe uint GetValue(uint* aThis, int aIndex) {
aThis += 3;
uint xElementSize = *aThis;
@ -90,6 +100,8 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System {
throw new NotSupportedException("GetValue not supported in this situation!");
}
public static unsafe object GetValue(Array aThis, params int[] aIndices) { throw new NotImplementedException("Multidimensional arrays not supported yet!"); }
[PlugMethod(Signature = "System_Void__System_Array_SetValue_System_Object__System_Int32_")]
public static unsafe void SetValue(uint* aThis, uint aValue, int aIndex) {
aThis += 3;

View file

@ -1,4 +1,4 @@
//#define MTW_DEBUG
#define MTW_DEBUG
using System;
using System.Collections.Generic;
using System.Linq;
@ -8,6 +8,15 @@ using System.Xml;
using System.Reflection;
namespace Indy.IL2CPU.IL {
public class MethodBaseComparer : IComparer<MethodBase>
{
#region IComparer<MethodBase> Members
public int Compare(MethodBase x, MethodBase y)
{
return x.GetFullName().CompareTo(y.GetFullName());
}
#endregion
}
public abstract class InitVmtImplementationOp: Op {
public delegate int GetMethodIdentifierEventHandler(MethodBase aMethod);
public InitVmtImplementationOp(ILReader aReader, MethodInformation aMethodInfo)
@ -80,17 +89,27 @@ namespace Indy.IL2CPU.IL {
xDebug.WriteAttributeString("Id", i.ToString("X"));
#endif
Type xType = mTypes[i];
List<MethodBase> xEmittedMethods = new List<MethodBase>();
if (xType.IsInterface) { continue; }
// 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);
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);
xEmittedMethods.Add(xCtor, false);
}
}
foreach (var xIntf in xType.GetInterfaces()) {
var xIntfMap = xType.GetInterfaceMap(xIntf);
for (int xI = 0; xI < xIntfMap.InterfaceMethods.Length; xI++) {
if (Methods.Contains(xIntfMap.InterfaceMethods[xI])) {
xEmittedMethods.Add(xIntfMap.InterfaceMethods[xI], true);
}
}
}
Pushd("0" + i.ToString("X") + "h");
int? xBaseIndex = null;
if (xType.BaseType == null) {
@ -103,7 +122,7 @@ namespace Indy.IL2CPU.IL {
}
}
}
if (xBaseIndex == null) {
if (xBaseIndex == null) {
throw new Exception("Base type not found!");
}
#if MTW_DEBUG
@ -139,26 +158,22 @@ namespace Indy.IL2CPU.IL {
//Pushd("0");
Call(SetTypeInfoRef);
for (int j = 0; j < xEmittedMethods.Count; j++) {
MethodBase xMethod = xEmittedMethods[j];
MethodBase xMethod = xEmittedMethods.Keys[j];
var xMethodId =GetMethodIdentifier(xMethod);
if (xEmittedMethods.Values[j]) {
var xIntfMap = xType.GetInterfaceMap(xMethod.DeclaringType);
xMethod = xIntfMap.TargetMethods[Array.IndexOf<MethodBase>(xIntfMap.InterfaceMethods, xMethod)];
}
#if MTW_DEBUG
xDebug.WriteStartElement("Method");
xDebug.WriteAttributeString("Id", GetMethodIdentifier(xMethod).ToString("X"));
xDebug.WriteAttributeString("Id", xMethodId.ToString("X"));
xDebug.WriteAttributeString("Name", xMethod.GetFullName());
xDebug.WriteEndElement();
#endif
if (xMethod.DeclaringType.FullName == "System.Object" && xMethod.Name == "Equals" && xMethod.GetParameters().Length == 1 && xMethod.GetParameters()[0].ParameterType.FullName == "System.Object") {
System.Diagnostics.Debugger.Break();
}
Pushd("0" + i.ToString("X") + "h");
Pushd("0" + j.ToString("X") + "h");
ParameterInfo[] xParams = xMethod.GetParameters();
Type[] xMethodParams = new Type[xParams.Length];
for (int k = 0; k < xParams.Length; k++) {
xMethodParams[k] = xParams[k].ParameterType;
}
Pushd("0" + GetMethodIdentifier(xMethod).ToString("X") + "h");
Pushd("0" + xMethodId.ToString("X") + "h");
Pushd(Label.GenerateLabelName(xMethod));
//xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0";
//xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod));

View file

@ -70,10 +70,11 @@ namespace Indy.IL2CPU.IL {
}
public virtual IList<Assembly> GetPlugAssemblies() {
List<Assembly> xResult = new List<Assembly>();
xResult.Add(typeof(OpCodeMap).Assembly);
xResult.Add(Assembly.Load("Indy.IL2CPU"));
return xResult;
var xResult = new List<Assembly> {
typeof(OpCodeMap).Assembly,
Assembly.Load("Indy.IL2CPU")
};
return xResult;
}
public MethodBase GetCustomMethodImplementation(string aOrigMethodName, bool aInMetalMode) {

View file

@ -473,61 +473,102 @@ namespace Indy.IL2CPU {
xOp.Assemble();
}
private void ScanForMethodsToIncludeForVMT() {
List<Type> xCheckedTypes = new List<Type>();
foreach (MethodBase xMethod in mMethods.Keys) {
if (xMethod.IsStatic) {
continue;
}
Type xCurrentType = xMethod.DeclaringType;
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) {
xCheckedTypes.Add(xCurrentType);
}
}
foreach (Type xType in mTypes) {
if (!xCheckedTypes.Contains(xType, mTypesEqualityComparer)) {
xCheckedTypes.Add(xType);
}
}
for (int i = 0; i < xCheckedTypes.Count; i++) {
Type xCurrentType = xCheckedTypes[i];
while (xCurrentType != null) {
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) {
xCheckedTypes.Add(xCurrentType);
}
if (xCurrentType.FullName == "System.Object") {
break;
}
if (xCurrentType.BaseType == null) {
break;
}
xCurrentType = xCurrentType.BaseType;
}
}
foreach (Type xTD in xCheckedTypes) {
foreach (MethodBase xMethod in xTD.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) {
if (!xMethod.IsStatic) {
if (xTD.BaseType == null) {
continue;
}
if (xMethod.IsVirtual && !xMethod.IsConstructor && !xMethod.IsFinal) {
Type xCurrentInspectedType = xTD.BaseType;
ParameterInfo[] xParams = xMethod.GetParameters();
Type[] xMethodParams = new Type[xParams.Length];
for (int i = 0; i < xParams.Length; i++) {
xMethodParams[i] = xParams[i].ParameterType;
}
MethodBase xBaseMethod = GetUltimateBaseMethod(xMethod, xMethodParams, xTD);
if (xBaseMethod != null && xBaseMethod != xMethod) {
if (mMethods.ContainsKey(xBaseMethod)) {
QueueMethod(xMethod);
}
}
}
}
}
}
}
private void ScanForMethodsToIncludeForVMT()
{
List<Type> xCheckedTypes = new List<Type>();
foreach (MethodBase xMethod in mMethods.Keys)
{
if (xMethod.IsStatic)
{
continue;
}
Type xCurrentType = xMethod.DeclaringType;
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer))
{
xCheckedTypes.Add(xCurrentType);
}
}
foreach (Type xType in mTypes)
{
if (!xCheckedTypes.Contains(xType, mTypesEqualityComparer))
{
xCheckedTypes.Add(xType);
}
}
for (int i = 0; i < xCheckedTypes.Count; i++)
{
Type xCurrentType = xCheckedTypes[i];
while (xCurrentType != null)
{
if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer))
{
xCheckedTypes.Add(xCurrentType);
}
if (xCurrentType.FullName == "System.Object")
{
break;
}
if (xCurrentType.BaseType == null)
{
break;
}
xCurrentType = xCurrentType.BaseType;
}
}
foreach (Type xTD in xCheckedTypes)
{
foreach (MethodBase xMethod in xTD.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
if (!xMethod.IsStatic)
{
if (xTD.BaseType == null)
{
continue;
}
if (xMethod.IsVirtual && !xMethod.IsConstructor && !xMethod.IsFinal)
{
Type xCurrentInspectedType = xTD.BaseType;
ParameterInfo[] xParams = xMethod.GetParameters();
Type[] xMethodParams = new Type[xParams.Length];
for (int i = 0; i < xParams.Length; i++)
{
xMethodParams[i] = xParams[i].ParameterType;
}
MethodBase xBaseMethod = GetUltimateBaseMethod(xMethod, xMethodParams, xTD);
if (xBaseMethod != null && xBaseMethod != xMethod)
{
if (mMethods.ContainsKey(xBaseMethod))
{
QueueMethod(xMethod);
}
}
}
}
}
}
for(int j = 0; j < mMethods.Count;j++){
var xMethod = mMethods.Skip(j).First();
if (xMethod.Key.DeclaringType.IsInterface)
{
var xInterface = xMethod.Key.DeclaringType;
foreach (var xImplType in mTypes)
{
if (xImplType.IsInterface) { continue; }
if (xImplType.GetInterfaces().Contains(xInterface))
{
var xIntfMap = xImplType.GetInterfaceMap(xInterface);
for (int i = 0; i < xIntfMap.InterfaceMethods.Length; i++)
{
if (mMethods.ContainsKey(xIntfMap.InterfaceMethods[i]))
{
QueueMethod(xIntfMap.TargetMethods[i]);
}
}
}
}
}
}
}
private static MethodBase GetUltimateBaseMethod(MethodBase aMethod, Type[] aMethodParams, Type aCurrentInspectedType) {
MethodBase xBaseMethod = null;
@ -780,7 +821,7 @@ namespace Indy.IL2CPU {
continue;
}
string xMethodName = Label.GenerateLabelName(xCurrentMethod);
TypeInformation xTypeInfo = null;
TypeInformation xTypeInfo = null;
{
if (!xCurrentMethod.IsStatic) {
xTypeInfo = GetTypeInfo(xCurrentMethod.DeclaringType);
@ -1161,13 +1202,20 @@ MethodInformation xMethodInfo = GetMethodInfo(xCurrentMethod, xCurrentMethod, xM
foreach (MethodBase xOrigMethodDef in xTypeRef.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)) {
string xOrigStrippedSignature = GetStrippedMethodBaseFullName(xOrigMethodDef);
if (xOrigStrippedSignature == xStrippedSignature) {
if (mPlugMethods.ContainsKey(Label.GenerateLabelName(xOrigMethodDef)))
{
System.Diagnostics.Debugger.Break();
}
mPlugMethods.Add(Label.GenerateLabelName(xOrigMethodDef), xMethod);
}
}
foreach (MethodBase xOrigMethodDef in xTypeRef.GetConstructors(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)) {
string xOrigStrippedSignature = GetStrippedMethodBaseFullName(xOrigMethodDef);
if (xOrigStrippedSignature == xStrippedSignature) {
mPlugMethods.Add(Label.GenerateLabelName(xOrigMethodDef), xMethod);
if (mPlugMethods.ContainsKey(Label.GenerateLabelName(xOrigMethodDef)))
{
System.Diagnostics.Debugger.Break();
} mPlugMethods.Add(Label.GenerateLabelName(xOrigMethodDef), xMethod);
}
}
}

View file

@ -7,8 +7,10 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace Indy.IL2CPU {
[DebuggerStepThrough]
public static class GCImplementation {
private static int mLock = 0;
private static void AcquireLock() {

View file

@ -2,9 +2,10 @@
using System.Collections.Generic;
using System.Text;
using Cosmos.Build.Windows;
using System.Collections;
namespace MatthijsTest {
public class Program {
public class Program {
#region Cosmos Builder logic
// Most users wont touch this. This will call the Cosmos Build tool
@ -15,6 +16,20 @@ namespace MatthijsTest {
#endregion
public class MessageContainer : IEnumerable
{
public IEnumerator GetEnumerator() {
yield return "String1";
yield return "String2";
yield return "String3";
yield return "String4";
yield return "String5";
}
}
public static void GetResumeAndResume(ref uint aSuspend)
{
aSuspend = 0;
@ -22,8 +37,10 @@ namespace MatthijsTest {
}
public static void Init() {
//Cosmos.Kernel.Boot.Default();
var xTest = new Object();
var xTest = (IEnumerable)new string[] { "String1", "String2", "String3" };
foreach(string xItem in xTest){
Console.WriteLine(xItem);
}
}
}
}