Created plugs to make Hashtable work (at least when an object is key).

There are issue however:
1. IL2CPU modifications are needed (see the PR for the list of the PR of IL2CPU to merge to make this usable)
2. Some fix in IL2CPU seems to give problems with Dictionary (VMT problem again?)
3. Hashtable with valuetype as key doesn't work (ContainsKey() always return false)
This commit is contained in:
fanoI 2018-02-25 15:27:39 +01:00
parent 9d54d0b072
commit e240641863
7 changed files with 134 additions and 9 deletions

View file

@ -0,0 +1,57 @@
using System;
using System.Collections;
using Cosmos.TestRunner;
//using Cosmos.Compiler.Tests.Bcl.Helper;
using Cosmos.Debug.Kernel;
namespace Cosmos.Compiler.Tests.Bcl.System.Collections.Not_Generic
{
class HashtableTest
{
private static Debugger myDebugger = new Debugger("System", "HashtableTest");
public static void Execute()
{
var h = new Hashtable();
Assert.IsTrue(h != null, "Hashtable ctor returns but h is null");
h.Add("One", "One");
//h.Add(42, "Test");
Assert.IsTrue(h.ContainsKey("One"), "Hashtable.ContainsKey() failed: existing key not found");
Assert.IsFalse(h.ContainsKey("Two"), "Hashtable.ContainsKey() failed: not existing key not found");
Assert.IsTrue((string)h["One"] == "One", "Hashtable indexer failed: existing value not found");
Assert.IsTrue(h["Two"] == null, "Hashtable indexer failed: not existing value not found");
/* The indexer written in this way should be the same thing of Add("Two", "Two") */
h["Two"] = "Two";
Assert.IsTrue((string)h["Two"] == "Two", "Hashtable indexer failed: existing value (II) not found");
Assert.IsTrue(h.Count == 2, "Hashtable Count failed: value != 2");
/*
* Got Il2CPU exception:
* System.Exception: Original method argument $this is a reference type. Plug attribute first argument is not an argument type, nor was it marked with ObjectPointerAccessAttribute! Method: SystemObjectSystemArrayGetValueSystemInt32 Parameter: aThis
* at Cosmos.IL2CPU.AppAssembler.GenerateMethodForward(_MethodInfo aFrom, _MethodInfo aTo) in C:\Users\fano\Documents\GitHub\Cosmos\IL2CPU\source\Cosmos.IL2CPU\AppAssembler.cs:line 1309
* at Cosmos.IL2CPU.ILScanner.Assemble() in C:\Users\fano\Documents\GitHub\Cosmos\IL2CPU\source\Cosmos.IL2CPU\ILScanner.cs:line 951
* at Cosmos.IL2CPU.ILScanner.Execute(MethodBase aStartMethod) in C:\Users\fano\Documents\GitHub\Cosmos\IL2CPU\source\Cosmos.IL2CPU\ILScanner.cs:line 255
* at Cosmos.IL2CPU.CompilerEngine.Execute() in C:\Users\fano\Documents\GitHub\Cosmos\IL2CPU\source\Cosmos.IL2CPU\CompilerEngine.cs:line 168
* Error invoking 'dotnet'.
*/
#if false
foreach (var k in h.Keys)
{
Assert.IsTrue((string)k == "One" || (string)k == "Two", "Hashtable key collection returns invalid key");
}
#endif
Hashtable h2 = new Hashtable();
h2.Add(42, "FortyTwo");
Assert.IsTrue(h2.ContainsKey(42), "h2.ContainsKey() failed: existing key not found");
}
}
}

View file

@ -0,0 +1,19 @@
using Cosmos.Core_Plugs.System;
using IL2CPU.API.Attribs;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Cosmos.Core_Plugs
{
[Plug(Target = typeof(global::System.RuntimeFieldHandle))]
public static class RuntimeFieldHandleImpl
{
[PlugMethod(Signature = "System_Object__System_RuntimeFieldHandle_GetValue_System_Reflection_RtFieldInfo__System_Object__System_RuntimeType__System_RuntimeType___System_Boolean_")]
public static object GetValue(FieldInfo field, object instance, object fieldType, object declaringType, ref bool domainInitialized)
{
throw new NotImplementedException("RuntimeFieldHandle.GetValue()");
}
}
}

View file

@ -5,17 +5,18 @@ using IL2CPU.API.Attribs;
namespace Cosmos.Core_Plugs.System
{
[Plug(Target = typeof(Delegate), Inheritable = true)]
[PlugField(FieldType = typeof(int), FieldId = "$$ArgSize$$")]
[PlugField(FieldType = typeof(int), FieldId = "$$ReturnsValue$$")]
[Plug(Target = typeof(Delegate))]
public static class DelegateImpl
{
[PlugMethod(Signature = "System_Boolean__System_Delegate_Equals_System_Object_")]
public static bool Equals(Delegate aThis, object aThat)
{
// todo: implement proper Delegate.Equals(object)
return false;
//return false;
throw new NotImplementedException();
}
[PlugMethod(Signature = "System_Boolean__System_Delegate_InternalEqualTypes_System_Object__System_Object_")]
public static unsafe bool InternalEqualTypes([ObjectPointerAccess] uint** a, [ObjectPointerAccess] uint** b)
{
var xTypeA = a[0][0];
@ -23,7 +24,13 @@ namespace Cosmos.Core_Plugs.System
return xTypeA == xTypeB;
}
}
[Plug(Target = typeof(Delegate), Inheritable = true)]
[PlugField(FieldType = typeof(int), FieldId = "$$ArgSize$$")]
[PlugField(FieldType = typeof(int), FieldId = "$$ReturnsValue$$")]
public static class DelegateImplInherit
{
[PlugMethod(Signature = "System_MulticastDelegate__System_Delegate_InternalAllocLike_System_Delegate_")]
public static unsafe uint InternalAllocLike(uint* aDelegate)
{
@ -38,5 +45,14 @@ namespace Cosmos.Core_Plugs.System
}
return xResultAddr;
}
[PlugMethod(Signature = "System_Boolean__System_Delegate_Equals_System_Object_")]
public static bool Equals(Delegate aThis, object aThat)
{
// todo: implement proper Delegate.Equals(object)
//return false;
throw new NotImplementedException();
}
}
}

View file

@ -19,7 +19,12 @@ namespace Cosmos.Core_Plugs.System.Globalization
public static int GetHashCode(CultureInfo aThis)
{
throw new NotImplementedException();
throw new NotImplementedException("CultureInfo.GetHashCode()");
}
public static bool Equals(CultureInfo aThis, object value)
{
throw new NotImplementedException("CultureInfo.Equals()");
}
public static void CCtor()

View file

@ -0,0 +1,15 @@
using System;
using System.Threading;
using IL2CPU.API.Attribs;
namespace Cosmos.System_Plugs.System.Threading
{
[Plug(Target = typeof(global::System.Threading.SpinWait))]
public static class SpinWaitImpl
{
public static void SpinOnce(ref SpinWait aThis)
{
throw new NotImplementedException("SpinWait.SpinOnce()");
}
}
}

View file

@ -1,13 +1,11 @@
using System;
using System.Threading;
using Cosmos.HAL;
using IL2CPU.API.Attribs;
namespace Cosmos.System_Plugs.System.Threading
{
[Plug(Target = typeof(Thread))]
//[Plug(Target = typeof(Thread))]
[Plug(TargetName = "System.Threading.Thread")]
public static class ThreadImpl
{
public static void Sleep(TimeSpan timeout)
@ -19,5 +17,15 @@ namespace Cosmos.System_Plugs.System.Threading
{
Global.PIT.Wait((uint)millisecondsTimeout);
}
public static bool Yield()
{
throw new NotImplementedException("Thread.Yield()");
}
public static void SpinWaitInternal(object iterations)
{
throw new NotImplementedException("Thread.SpinWaitInternal()");
}
}
}

View file

@ -24,6 +24,11 @@ namespace Cosmos.System_Plugs.System
throw new NotImplementedException("ValueType.GetHashCodeOfPtr()");
}
public static bool Equals(ValueType aThis, object obj)
{
throw new NotImplementedException("ValueType.Equals()");
}
//public static string ToString(ValueType aThis)
//{
// return "<ValueType.ToString not yet implemented!>";