Skip to content

Commit

Permalink
Generic plugs work now.
Browse files Browse the repository at this point in the history
  • Loading branch information
mterwoord committed Jun 25, 2016
1 parent 0af938b commit 1433340
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 11 deletions.
4 changes: 2 additions & 2 deletions Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ public static void Apply(Engine engine)

// Sets the time before an error is registered. For example if set to 60 then if a kernel runs for more than 60 seconds then
// that kernel will be marked as a failure and terminated
engine.AllowedSecondsInKernel = 1800;
engine.AllowedSecondsInKernel = 30;

// If you want to test only specific platforms, add them to the list, like next line. By default, all platforms are run.
engine.RunTargets.Add(RunTargetEnum.Bochs);

// If you're working on the compiler (or other lower parts), you can choose to run the compiler in process
// one thing to keep in mind though, is that this only works with 1 kernel at a time!
//engine.RunIL2CPUInProcess = true;
engine.RunIL2CPUInProcess = true;
engine.TraceAssembliesLevel = TraceAssemblies.User;
engine.EnableStackCorruptionChecks = true;
engine.StackCorruptionChecksLevel = StackCorruptionDetectionLevel.AllInstructions;
Expand Down
3 changes: 2 additions & 1 deletion Users/Matthijs/DebugCompiler/MyEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class RunKernels
[TestCaseSource(typeof(MySource), nameof(MySource.ProvideData))]
public void Test(Type kernelToRun)
{
Assert.Fail();
Environment.CurrentDirectory = Path.GetDirectoryName(typeof(RunKernels).Assembly.Location);

var xEngine = new Engine();
Expand All @@ -25,7 +26,7 @@ public void Test(Type kernelToRun)
//xEngine.RunWithGDB = true;
// If you're working on the compiler (or other lower parts), you can choose to run the compiler in process
// one thing to keep in mind though, is that this only works with 1 kernel at a time!
xEngine.RunIL2CPUInProcess = false;
xEngine.RunIL2CPUInProcess = true;
xEngine.TraceAssembliesLevel = TraceAssemblies.User;

xEngine.EnableStackCorruptionChecks = true;
Expand Down
6 changes: 5 additions & 1 deletion source/Cosmos.IL2CPU/ILScanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,10 @@ protected void ScanMethod(MethodBase aMethod, bool aIsPlug, string sourceItem)
{
Queue(((SysReflection.MethodInfo)aMethod).ReturnType, aMethod, "Return Type");
}

if (aMethod.GetFullName().IndexOf("CreateComparer", StringComparison.OrdinalIgnoreCase)!=-1)
{
;
}
// Scan virtuals
#region Virtuals scan
if (!xIsDynamicMethod && aMethod.IsVirtual)
Expand Down Expand Up @@ -487,6 +490,7 @@ protected void ScanMethod(MethodBase aMethod, bool aIsPlug, string sourceItem)
if (!aIsPlug && !xIsDynamicMethod)
{
// Check to see if method is plugged, if it is we don't scan body

xPlug = mPlugManager.ResolvePlug(aMethod, xParamTypes);
if (xPlug != null)
{
Expand Down
87 changes: 81 additions & 6 deletions source/Cosmos.IL2CPU/PlugManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public class PlugManager
// List of inheritable plugs. Plugs that start at an ancestor and plug all
// descendants. For example, delegates
protected Dictionary<Type, List<Type>> mPlugImplsInhrt = new Dictionary<Type, List<Type>>();

// same as above 2 fields, except for generic plugs
protected Dictionary<Type, List<Type>> mGenericPlugImpls = new Dictionary<Type, List<Type>>();
protected Dictionary<Type, List<Type>> mGenericPlugImplsInhrt = new Dictionary<Type, List<Type>>();

// list of field plugs
protected IDictionary<Type, IDictionary<string, PlugFieldAttribute>> mPlugFields = new Dictionary<Type, IDictionary<string, PlugFieldAttribute>>();

Expand Down Expand Up @@ -121,7 +126,15 @@ public void FindPlugImpls()
// TODO: Integrate with builder options to allow Mono support again.
if (!xAttrib.IsMonoOnly)
{
var mPlugs = xAttrib.Inheritable ? mPlugImplsInhrt : mPlugImpls;
Dictionary<Type, List<Type>> mPlugs;
if (xTargetType.ContainsGenericParameters)
{
mPlugs = xAttrib.Inheritable ? mGenericPlugImplsInhrt : mGenericPlugImpls;
}
else
{
mPlugs = xAttrib.Inheritable ? mPlugImplsInhrt : mPlugImpls;
}
List<Type> xImpls;
if (mPlugs.TryGetValue(xTargetType, out xImpls))
{
Expand All @@ -145,6 +158,7 @@ public void ScanFoundPlugs()
ScanPlugs(mPlugImpls);
ScanPlugs(mPlugImplsInhrt);
}

public void ScanPlugs(Dictionary<Type, List<Type>> aPlugs)
{
foreach (var xPlug in aPlugs)
Expand Down Expand Up @@ -341,7 +355,7 @@ public void ScanPlugs(Dictionary<Type, List<Type>> aPlugs)
}
}

public MethodBase ResolvePlug(Type aTargetType, List<Type> aImpls, MethodBase aMethod, Type[] aParamTypes)
private MethodBase ResolvePlug(Type aTargetType, List<Type> aImpls, MethodBase aMethod, Type[] aParamTypes)
{
//TODO: This method is "reversed" from old - remember that when porting
MethodBase xResult = null;
Expand Down Expand Up @@ -526,6 +540,10 @@ public MethodBase ResolvePlug(Type aTargetType, List<Type> aImpls, MethodBase aM
xResult = xSigMethod;
break;
}
//if (aMethod.DeclaringType.IsGenericTypeDefinition)
//{
// if (xTargetMethod.GetF)
//}
if (xAttrib != null && xAttrib.Signature != null)
{
var xName = DataMember.FilterStringForIncorrectChars(LabelName.GenerateFullName(aMethod));
Expand Down Expand Up @@ -642,20 +660,21 @@ public MethodBase ResolvePlug(Type aTargetType, List<Type> aImpls, MethodBase aM
//}
return xResult;
}

public MethodBase ResolvePlug(MethodBase aMethod, Type[] aParamTypes)
{
MethodBase xResult = null;
if (aMethod.Name == "CreateComparer")
{
;
}
var xMethodKey = BuildMethodKeyName(aMethod);
if (ResolvedPlugs.Contains(xMethodKey, out xResult))
{
return xResult;
}
else
{
// TODO: Right now plugs are compiled in, even if they are not needed.
// Maybe change this so plugs that are not needed are not compiled in?
// To do so, maybe plugs could be marked as they are used

List<Type> xImpls;
// Check for exact type plugs first, they have precedence
if (mPlugImpls.TryGetValue(aMethod.DeclaringType, out xImpls))
Expand Down Expand Up @@ -683,6 +702,62 @@ public MethodBase ResolvePlug(MethodBase aMethod, Type[] aParamTypes)
}
}
}
if (xResult == null)
{
xImpls = null;
if (aMethod.DeclaringType.IsGenericType)
{
var xMethodDeclaringTypeDef = aMethod.DeclaringType.GetGenericTypeDefinition();
if (mGenericPlugImpls.TryGetValue(xMethodDeclaringTypeDef, out xImpls))
{
var xBindingFlagsToFindMethod = BindingFlags.Default;
if (aMethod.IsPublic)
{
xBindingFlagsToFindMethod = BindingFlags.Public;
}
else
{
// private
xBindingFlagsToFindMethod = BindingFlags.NonPublic;
}
if (aMethod.IsStatic)
{
xBindingFlagsToFindMethod |= BindingFlags.Static;
}
else
{
xBindingFlagsToFindMethod |= BindingFlags.Instance;
}
var xGenericMethod = (from item in xMethodDeclaringTypeDef.GetMethods(xBindingFlagsToFindMethod)
where item.Name == aMethod.Name
&& item.GetParameters().Length == aParamTypes.Length
select item).SingleOrDefault();
if (xGenericMethod != null)
{
var xTempResult = ResolvePlug(xMethodDeclaringTypeDef, xImpls, xGenericMethod, aParamTypes);

if (xTempResult != null)
{
if (xTempResult.DeclaringType.IsGenericTypeDefinition)
{
var xConcreteTempResultType = xTempResult.DeclaringType.MakeGenericType(aMethod.DeclaringType.GetGenericArguments());
xResult = (from item in xConcreteTempResultType.GetMethods(BindingFlags.Static | BindingFlags.Public)
where item.Name == aMethod.Name
&& item.GetParameters().Length == aParamTypes.Length
select item).SingleOrDefault();
}
}
;
;
;
;

}

///
}
}
}

ResolvedPlugs.Add(xMethodKey, xResult);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ public static void cctor() {
//TODO: do something
}

public new static bool Equals(object o1, object o2)
{
if (o1 == null
&& o2 == null)
{
return true;
}
if (o1 == null
|| o2 == null)
{
return false;
}
return object.Equals(o1, o2);
}

[Inline(TargetPlatform = TargetPlatform.x86)]
[PlugMethod]
public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle) {
Expand Down
1 change: 1 addition & 0 deletions source/Cosmos.System.Plugs/Cosmos.System.Plugs.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
<Reference Include="System.Drawing" />
</ItemGroup>
<ItemGroup>
<Compile Include="System\Collections\Generic\EqualityComparerImpl.cs" />
<Compile Include="System\DecimalImpl.cs" />
<Compile Include="System\Mda.cs" />
<Compile Include="System\Security\Cryptography\CryptoConfigImpl.cs" />
Expand Down
7 changes: 6 additions & 1 deletion source/Cosmos.System.Plugs/System/CharImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public static string ToString(ref char aThis)
return new string(xResult);
}

public static bool Equals(ref char aThis, char that)
{
return aThis == that;
}

public static char ToUpper(char aThis)
{
// todo: properly implement Char.ToUpper()
Expand All @@ -50,4 +55,4 @@ public static bool IsWhiteSpace(char aChar)
return aChar == ' ' || aChar == '\t';
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using Cosmos.IL2CPU.Plugs;

namespace Cosmos.System.Plugs.System.Collections.Generic
{
[Plug(Target = typeof(EqualityComparer<>))]
public static class EqualityComparerImpl<T>
{
public static EqualityComparer<T> CreateComparer()
{
throw new Exception("Create comparer not yet implemented!");
}
}
}

0 comments on commit 1433340

Please sign in to comment.