Get compiler working.

This commit is contained in:
Charles Betros 2016-12-29 00:20:34 -06:00
parent 004dbfba0a
commit 216d8a3209
18 changed files with 5399 additions and 2073 deletions

View file

@ -58,6 +58,26 @@
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\source\Cosmos.Core.Plugs.Asm\Cosmos.Core.Plugs.Asm.csproj">
<Name>Cosmos.Core.Plugs.Asm</Name>
<Project>{fc7919d8-374c-4d13-95a9-0b248c372efe}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Core.Plugs\Cosmos.Core.Plugs.csproj">
<Name>Cosmos.Core.Plugs</Name>
<Project>{09273ea1-d3ea-4ccf-aabc-4a209eb367b7}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Debug.Kernel.Plugs.Asm\Cosmos.Debug.Kernel.Plugs.Asm.csproj">
<Name>Cosmos.Debug.Kernel.Plugs.Asm</Name>
<Project>{b97a2956-c363-47f2-a6aa-b4fccff4d315}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.System.Plugs\Cosmos.System.Plugs.csproj">
<Name>Cosmos.System.Plugs</Name>
<Project>{e52f6162-5094-49f4-a685-d08e5480bac2}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="..\Guess\GuessKernel.csproj">
<Name>GuessKernel</Name>
<Project>{1780684c-6b7f-4360-81c0-69204e343a08}</Project>

View file

@ -43,10 +43,42 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\source\Cosmos.Common\Cosmos.Common.csproj">
<Project>{b0957633-03c5-4531-9358-14d520f7ff78}</Project>
<Name>Cosmos.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Core.Common\Cosmos.Core.Common.csproj">
<Project>{5a38be55-d402-4de6-bb2b-f0360da1c1bd}</Project>
<Name>Cosmos.Core.Common</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Core.Memory\Cosmos.Core.Memory.csproj">
<Project>{06cc50c4-6ffd-42a8-85e2-309e187b345e}</Project>
<Name>Cosmos.Core.Memory</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Core.Plugs\Cosmos.Core.Plugs.csproj">
<Project>{09273ea1-d3ea-4ccf-aabc-4a209eb367b7}</Project>
<Name>Cosmos.Core.Plugs</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Core\Cosmos.Core.csproj">
<Project>{51efe968-249d-445c-9184-37c4ae1edf4e}</Project>
<Name>Cosmos.Core</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.Debug.Kernel\Cosmos.Debug.Kernel.csproj">
<Project>{dc93aed0-a9bf-42c4-ac7b-fa9b2063e5d1}</Project>
<Name>Cosmos.Debug.Kernel</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.HAL\Cosmos.HAL.csproj">
<Project>{bc775926-731c-449d-8e8a-90d1d8116872}</Project>
<Name>Cosmos.HAL</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.IL2CPU.Plugs\Cosmos.IL2CPU.Plugs.csproj">
<Project>{12a519aa-7af2-4873-8ad1-fab5a76448b1}</Project>
<Name>Cosmos.IL2CPU.Plugs</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.System.Plugs\Cosmos.System.Plugs.csproj">
<Project>{e52f6162-5094-49f4-a685-d08e5480bac2}</Project>
<Name>Cosmos.System.Plugs</Name>
</ProjectReference>
<ProjectReference Include="..\..\source\Cosmos.System\Cosmos.System.csproj">
<Project>{19d31813-caf2-42d9-a1e3-448913de6ce2}</Project>
<Name>Cosmos.System</Name>

View file

@ -3,18 +3,14 @@
"win7-x64": {}
},
"dependencies": {
"NETStandard.Library": "1.6.1",
"Microsoft.NETCore.Platforms": "1.1.0",
"Microsoft.NETCore.Runtime.CoreCLR": "1.1.0",
"Microsoft.NETCore.Targets": "1.1.0",
"System.Console": "4.3.0",
"System.Reflection": "4.3.0",
"System.Reflection.Primitives": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0"
"Microsoft.NETCore.Targets": "1.1.0"
},
"frameworks": {
"netcoreapp1.0": {
"netstandard1.6": {
"imports": "portable-net452"
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -7,10 +7,6 @@ using Cosmos.Build.MSBuild;
using Cosmos.IL2CPU;
using IL2CPU;
using Microsoft.Win32;
using NuGet;
using NuGet.Configuration;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
namespace Cosmos.TestRunner.Core
{
@ -113,6 +109,13 @@ namespace Cosmos.TestRunner.Core
AdditionalSearchDirs.Add(Path.GetDirectoryName(kernelFileName));
References.Add(kernelFileName);
// TODO: Need a better way to do this.
foreach (var xFile in new DirectoryInfo(Path.GetDirectoryName(kernelFileName)).GetFiles("*Plugs*.dll"))
{
References.Add(xFile.FullName);
}
//References.Add(typeof(Cosmos.Debug.Kernel.Plugs.Asm.DebugBreak).Assembly.Location);
//References.Add(typeof(Cosmos.Core.Plugs.Asm.ArrayImpl).Assembly.Location);
var xArguments = new List<string>
{

View file

@ -7,7 +7,7 @@ using Cosmos.IL2CPU.Plugs;
namespace Cosmos.Core.Plugs
{
[Plug(TargetName = "Cosmos.IL2CPU.GCImplementation, Cosmos.IL2CPU")]
[Plug(Target = typeof(Cosmos.Core.Common.GCImplementation))]
public static class GCImplementionImpl
{
public static uint AllocNewObject(uint aSize)

View file

@ -3,9 +3,10 @@
"netcoreapp1.0.app": {}
},
"dependencies": {
"NETStandard.Library": "1.6.1"
"NETStandard.Library": "1.6.1",
"Microsoft.NETCore.Portable.Compatibility": "1.0.2"
},
"frameworks": {
"netstandard1.5": {}
}
}
}

View file

@ -21928,6 +21928,7 @@
},
"projectFileDependencyGroups": {
"": [
"Microsoft.NETCore.Portable.Compatibility >= 1.0.2",
"NETStandard.Library >= 1.6.1"
],
".NETStandard,Version=v1.5": []

View file

@ -12,4 +12,4 @@
"imports": "portable-net452"
}
}
}
}

View file

@ -4,7 +4,6 @@
"net462.app": {}
},
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.2",
"NETStandard.Library": "1.6.1"
},
"frameworks": {

File diff suppressed because it is too large Load diff

View file

@ -777,12 +777,12 @@ namespace Cosmos.IL2CPU
{
if (xType.IsSubclassOf(aAssemblerBaseOp))
{
var xAttribs = (OpCodeAttribute[])xType.GetCustomAttributes(typeof(OpCodeAttribute), false);
var xAttribs = xType.GetCustomAttributes<OpCodeAttribute>(false);
foreach (var xAttrib in xAttribs)
{
var xOpCode = (ushort)xAttrib.OpCode;
var xCtor = xType.GetConstructor(new Type[] { typeof(Assembler.Assembler) });
var xILOp = (ILOp)xCtor.Invoke(new Object[] { Assembler });
var xILOp = (ILOp)xCtor.Invoke(new object[] { Assembler });
if (xOpCode <= 0xFF)
{
mILOpsLo[xOpCode] = xILOp;
@ -1146,8 +1146,8 @@ namespace Cosmos.IL2CPU
xFieldName = DataMember.GetStaticFieldName(aField);
if (Cosmos.Assembler.Assembler.CurrentInstance.DataMembers.Count(x => x.Name == xFieldName) == 0)
{
var xItemList = (from item in aField.GetCustomAttributes(false)
where item.GetType().FullName == "ManifestResourceStreamAttribute"
var xItemList = (from item in aField.CustomAttributes
where item.AttributeType.FullName == "ManifestResourceStreamAttribute"
select item).ToList();
object xItem = null;
@ -1272,7 +1272,7 @@ namespace Cosmos.IL2CPU
if (!aTo.IsWildcard)
{
var xObjectPointerAccessAttrib = xParams[0].GetCustomAttributes<ObjectPointerAccessAttribute>(true).FirstOrDefault();
var xObjectPointerAccessAttrib = xParams[0].GetReflectionOnlyCustomAttributes<ObjectPointerAccessAttribute>(true).FirstOrDefault();
if (xObjectPointerAccessAttrib != null)
{
XS.Comment("Skipping the reference to the next object reference.");
@ -1295,13 +1295,13 @@ namespace Cosmos.IL2CPU
var xOriginalParamsIdx = 0;
foreach (var xParam in xParams)
{
var xFieldAccessAttrib = xParam.GetCustomAttributes<FieldAccessAttribute>(true).FirstOrDefault();
var xObjectPointerAccessAttrib = xParam.GetCustomAttributes<ObjectPointerAccessAttribute>(true).FirstOrDefault();
var xFieldAccessAttrib = xParam.GetReflectionOnlyCustomAttributes<FieldAccessAttribute>(true).FirstOrDefault();
var xObjectPointerAccessAttrib = xParam.GetReflectionOnlyCustomAttributes<ObjectPointerAccessAttribute>(true).FirstOrDefault();
if (xFieldAccessAttrib != null)
{
// field access
XS.Comment("Loading address of field '" + xFieldAccessAttrib.Name + "'");
var xFieldInfo = ResolveField(aFrom, xFieldAccessAttrib.Name, false);
XS.Comment("Loading address of field '" + xFieldAccessAttrib.GetArgumentValue<string>("Name") + "'");
var xFieldInfo = ResolveField(aFrom, xFieldAccessAttrib.GetArgumentValue<string>("Name"), false);
if (xFieldInfo.IsStatic)
{
Ldsflda(aFrom, xFieldInfo);

View file

@ -156,13 +156,13 @@ namespace Cosmos.IL2CPU
private static Ring GetRingFromAssembly(Assembly assembly)
{
var xRingAttrib = assembly.GetCustomAttributes<RingAttribute>().SingleOrDefault();
var xRingAttrib = assembly.GetReflectionOnlyCustomAttribute<RingAttribute>();
if (xRingAttrib == null)
{
return Ring.User;
}
return xRingAttrib.Ring;
return xRingAttrib.GetArgumentValue<Ring>("Ring");
}
private static void RingsWriteLine(string line, params object[] args)

View file

@ -33,6 +33,8 @@ namespace Cosmos.IL2CPU
public string[] AdditionalSearchDirs { get; set; }
public string[] AdditionalReferences { get; set; }
private List<CompilerExtensionBase> mLoadedExtensions;
public bool DebugEnabled = false;
public bool StackCorruptionDetectionEnabled = false;
protected StackCorruptionDetectionLevel mStackCorruptionDetectionLevel = Cosmos.Build.Common.StackCorruptionDetectionLevel.MethodFooters;
@ -66,8 +68,80 @@ namespace Cosmos.IL2CPU
OnLogException?.Invoke(e);
}
private string CurrentDomain_AssemblyPath(string aShortName, Assembly aRequestingAssembly)
{
// Check nuget packages.
foreach (var xRef in AdditionalReferences)
{
var xAssemblyName = AssemblyName.GetAssemblyName(xRef);
if (xAssemblyName.Name == aShortName)
{
return xRef;
}
}
// Check search directories.
foreach (var xDir in mSearchDirs)
{
var xPath = Path.Combine(xDir, aShortName + ".dll");
if (File.Exists(xPath))
{
return xPath;
}
xPath = Path.Combine(xDir, aShortName + ".exe");
if (File.Exists(xPath))
{
return xPath;
}
}
if (aRequestingAssembly != null)
{
// check for path in as requested dll is stored, this makes refrenced dll project working
var xPathAsRequested = Path.Combine(Path.GetDirectoryName(aRequestingAssembly.Location), aShortName + ".dll");
if (File.Exists(xPathAsRequested))
{
return xPathAsRequested;
}
}
return null;
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
mStaticLog?.Invoke($"Resolving assembly '{args.Name}'.");
var xShortName = args.Name;
if (xShortName.Contains(','))
{
xShortName = xShortName.Substring(0, xShortName.IndexOf(','));
}
// Check already loaded assemblies.
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var xLoadedShortName = assembly.GetName().Name;
if (xLoadedShortName == xShortName)
{
return assembly;
}
}
string xPath = CurrentDomain_AssemblyPath(xShortName, args.RequestingAssembly);
if (!string.IsNullOrWhiteSpace(xPath))
{
return Assembly.LoadFrom(xPath);
}
mStaticLog?.Invoke($"Assembly '{args.Name}' not resolved!");
return null;
}
private Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
mStaticLog?.Invoke($"Resolving assembly '{args.Name}'.");
var xShortName = args.Name;
if (xShortName.Contains(','))
{
@ -84,36 +158,12 @@ namespace Cosmos.IL2CPU
}
}
// Check nuget packages.
foreach (var xRef in AdditionalReferences)
string xPath = CurrentDomain_AssemblyPath(xShortName, args.RequestingAssembly);
if (!string.IsNullOrWhiteSpace(xPath))
{
var xAssemblyName = AssemblyName.GetAssemblyName(xRef);
if (xAssemblyName.Name == xShortName)
{
return Assembly.ReflectionOnlyLoadFrom(xRef);
}
return Assembly.ReflectionOnlyLoadFrom(xPath);
}
// Check search directories.
foreach (var xDir in mSearchDirs)
{
var xPath = Path.Combine(xDir, xShortName + ".dll");
if (File.Exists(xPath))
{
return Assembly.ReflectionOnlyLoadFrom(xPath);
}
xPath = Path.Combine(xDir, xShortName + ".exe");
if (File.Exists(xPath))
{
return Assembly.ReflectionOnlyLoadFrom(xPath);
}
}
// check for path in as requested dll is stored, this makes refrenced dll project working
var xPathAsRequested = Path.Combine(Path.GetDirectoryName(args.RequestingAssembly.Location), xShortName + ".dll");
if (File.Exists(xPathAsRequested))
{
return Assembly.ReflectionOnlyLoadFrom(xPathAsRequested);
}
mStaticLog?.Invoke($"Assembly '{args.Name}' not resolved!");
return null;
}
@ -155,10 +205,10 @@ namespace Cosmos.IL2CPU
mSearchDirs.Add(CosmosPaths.UserKit);
mSearchDirs.Add(CosmosPaths.Kernel);
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
mDebugMode = (DebugMode)Enum.Parse(typeof(DebugMode), DebugMode);
mDebugMode = (DebugMode) Enum.Parse(typeof(DebugMode), DebugMode);
if (string.IsNullOrEmpty(TraceAssemblies))
{
mTraceAssemblies = Cosmos.Build.Common.TraceAssemblies.User;
@ -170,7 +220,7 @@ namespace Cosmos.IL2CPU
LogError("Invalid TraceAssemblies specified");
return false;
}
mTraceAssemblies = (TraceAssemblies)Enum.Parse(typeof(TraceAssemblies), TraceAssemblies);
mTraceAssemblies = (TraceAssemblies) Enum.Parse(typeof(TraceAssemblies), TraceAssemblies);
}
if (string.IsNullOrEmpty(StackCorruptionDetectionLevel))
@ -179,7 +229,7 @@ namespace Cosmos.IL2CPU
}
else
{
mStackCorruptionDetectionLevel = (StackCorruptionDetectionLevel)Enum.Parse(typeof(StackCorruptionDetectionLevel), StackCorruptionDetectionLevel);
mStackCorruptionDetectionLevel = (StackCorruptionDetectionLevel) Enum.Parse(typeof(StackCorruptionDetectionLevel), StackCorruptionDetectionLevel);
}
return true;
@ -357,7 +407,7 @@ namespace Cosmos.IL2CPU
if (!xType.IsGenericTypeDefinition && !xType.IsAbstract)
{
LogMessage($"Checking type {xType}");
if (xType.BaseType.Name == "Kernel")
if (xType.BaseType?.Name == "Kernel")
{
// found kernel?
if (xKernelType != null)
@ -371,10 +421,11 @@ namespace Cosmos.IL2CPU
}
}
//var xCompilerExtensionsMetas = xRef.GetReflectionOnlyCustomAttributes<CompilerExtensionAttribute>();
// TODO: Fix this.
//var xCompilerExtensionsMetas = xAssembly.GetReflectionOnlyCustomAttributes<CompilerExtensionAttribute>();
//foreach (var xMeta in xCompilerExtensionsMetas)
//{
// mLoadedExtensions.Add((CompilerExtensionBase)Activator.CreateInstance(xMeta.AttributeType));
// mLoadedExtensions.Add((CompilerExtensionBase) Activator.CreateInstance(xMeta.Type));
//}
}
}
@ -392,16 +443,182 @@ namespace Cosmos.IL2CPU
}
return xCtor;
}
private List<CompilerExtensionBase> mLoadedExtensions;
}
public static class AssemblyExtensions
public static class CustomAttributeExtensions
{
public static IEnumerable<CustomAttributeData> GetReflectionOnlyCustomAttributes<T>(this Assembly aAssembly)
public static CustomAttributeData GetReflectionOnlyCustomAttribute<T>(this Assembly aElement) where T : Attribute
{
var xAttributes = aAssembly.GetCustomAttributesData();
CustomAttributeData xData = null;
if (aElement == null)
{
throw new ArgumentNullException(nameof(aElement));
}
var xAttributes = aElement.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
if (xAttributes.Any())
{
if (xAttributes.Count > 1)
{
throw new Exception($"More than one attribute of type '{typeof(T)}' was found!");
}
xData = xAttributes[0];
}
return xData;
}
public static CustomAttributeData GetReflectionOnlyCustomAttribute<T>(this MemberInfo aElement, bool aInherit = false) where T : Attribute
{
CustomAttributeData xData = null;
if (aElement == null)
{
throw new ArgumentNullException(nameof(aElement));
}
var xAttributes = aElement.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
if (aInherit)
{
var xBaseType = aElement.ReflectedType?.BaseType;
while (!xAttributes.Any() && xBaseType != null)
{
xAttributes = xBaseType.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
xBaseType = xBaseType.BaseType;
}
}
if (xAttributes.Any())
{
if (xAttributes.Count > 1)
{
throw new Exception($"More than one attribute of type '{typeof(T)}' was found!");
}
xData = xAttributes[0];
}
return xData;
}
public static CustomAttributeData GetReflectionOnlyCustomAttribute<T>(this ParameterInfo aElement, bool aInherit = false) where T : Attribute
{
CustomAttributeData xData = null;
if (aElement == null)
{
throw new ArgumentNullException(nameof(aElement));
}
var xAttributes = aElement.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
if (aInherit)
{
var xBaseType = aElement.ParameterType.BaseType;
while (!xAttributes.Any() && xBaseType != null)
{
xAttributes = xBaseType.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
xBaseType = xBaseType.BaseType;
}
}
if (xAttributes.Any())
{
if (xAttributes.Count > 1)
{
throw new Exception($"More than one attribute of type '{typeof(T)}' was found!");
}
xData = xAttributes[0];
}
return xData;
}
public static List<CustomAttributeData> GetReflectionOnlyCustomAttributes<T>(this Assembly aElement) where T : Attribute
{
if (aElement == null)
{
throw new ArgumentNullException();
}
var xAttributes = aElement.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
return xAttributes;
}
public static List<CustomAttributeData> GetReflectionOnlyCustomAttributes<T>(this MemberInfo aElement, bool aInherit = false) where T : Attribute
{
if (aElement == null)
{
throw new ArgumentNullException();
}
var xAttributes = aElement.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
if (aInherit)
{
var xBaseType = aElement.ReflectedType?.BaseType;
while (!xAttributes.Any() && xBaseType != null)
{
xAttributes = xBaseType.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
xBaseType = xBaseType.BaseType;
}
}
return xAttributes;
}
public static List<CustomAttributeData> GetReflectionOnlyCustomAttributes<T>(this ParameterInfo aElement, bool aInherit = false) where T : Attribute
{
if (aElement == null)
{
throw new ArgumentNullException();
}
var xAttributes = aElement.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
if (aInherit)
{
var xBaseType = aElement.ParameterType.BaseType;
while (!xAttributes.Any() && xBaseType != null)
{
xAttributes = xBaseType.CustomAttributes.Where(x => x.AttributeType.FullName == typeof(T).FullName).ToList();
xBaseType = xBaseType.BaseType;
}
}
return xAttributes;
}
public static T GetArgumentValue<T>(this CustomAttributeData aElement, string aName)
{
if (aElement == null)
{
throw new ArgumentNullException(nameof(aElement));
}
if (string.IsNullOrWhiteSpace(aName))
{
throw new ArgumentNullException(nameof(aName));
}
var xArg = aElement.NamedArguments?.Where(x => x.MemberName == aName).ToList();
if (xArg != null && xArg.Any())
{
return (T) xArg[0].TypedValue.Value;
}
var xParams = aElement.Constructor.GetParameters().Where(x => x.Name == aName).ToList();
if (xParams != null && xParams.Any())
{
if (aElement.ConstructorArguments.Count > xParams[0].Position)
{
return (T) aElement.ConstructorArguments[xParams[0].Position].Value;
}
}
return default(T);
}
}
}

View file

@ -274,10 +274,10 @@ namespace Cosmos.IL2CPU
xInfo.Field = xField;
var xFieldOffsetAttrib =
xField.GetCustomAttributes(typeof(FieldOffsetAttribute), true).FirstOrDefault() as FieldOffsetAttribute;
xField.GetReflectionOnlyCustomAttributes<FieldOffsetAttribute>(true).FirstOrDefault();
if (xFieldOffsetAttrib != null)
{
xInfo.Offset = (uint)xFieldOffsetAttrib.Value;
xInfo.Offset = (uint)xFieldOffsetAttrib.GetArgumentValue<int>("Value");
}
aFields.Add(xInfo);

View file

@ -482,7 +482,7 @@ namespace Cosmos.IL2CPU
MethodBase xPlug = null;
// Plugs may use plugs, but plugs won't be plugged over themself
var inl = aMethod.GetCustomAttribute<InlineAttribute>();
var inl = aMethod.GetReflectionOnlyCustomAttribute<InlineAttribute>();
if (!aIsPlug && !xIsDynamicMethod)
{
// Check to see if method is plugged, if it is we don't scan body
@ -836,11 +836,11 @@ namespace Cosmos.IL2CPU
var xMethodType = MethodInfo.TypeEnum.Normal;
Type xPlugAssembler = null;
MethodInfo xPlugInfo = null;
var xMethodInline = xMethod.GetCustomAttribute<InlineAttribute>();
if (xMethodInline != null)
{
// inline assembler, shouldn't come here..
continue;
var xMethodInline = xMethod.GetReflectionOnlyCustomAttribute<InlineAttribute>();
if (xMethodInline != null)
{
// inline assembler, shouldn't come here..
continue;
}
var xMethodIdMethod = mItemsList.IndexOf(xMethod);
if (xMethodIdMethod == -1)
@ -850,8 +850,21 @@ namespace Cosmos.IL2CPU
if (xPlug != null)
{
xMethodType = MethodInfo.TypeEnum.NeedsPlug;
var xAttrib = xPlug.GetCustomAttribute<PlugMethodAttribute>();
var xInline = xPlug.GetCustomAttribute<InlineAttribute>();
var x = xPlug.GetReflectionOnlyCustomAttribute<PlugMethodAttribute>();
var xAttrib = new PlugMethodAttribute
{
Assembler = x.GetArgumentValue<Type>("Assembler"),
Enabled = x.GetArgumentValue<bool>("Enabled"),
IsMicrosoftdotNETOnly = x.GetArgumentValue<bool>("IsMicrosoftdotNETOnly"),
IsMonoOnly = x.GetArgumentValue<bool>("IsMonoOnly"),
IsOptional = x.GetArgumentValue<bool>("IsOptional"),
IsWildcard = x.GetArgumentValue<bool>("IsWildcard"),
PlugRequired = x.GetArgumentValue<bool>("PlugRequired"),
Signature = x.GetArgumentValue<string>("Signature"),
WildcardMatchParameters = x.GetArgumentValue<bool>("WildcardMatchParameters")
};
var xInline = xPlug.GetReflectionOnlyCustomAttribute<InlineAttribute>();
var xMethodIdPlug = mItemsList.IndexOf(xPlug);
if ((xMethodIdPlug == -1) && (xInline == null))
{
@ -910,10 +923,21 @@ namespace Cosmos.IL2CPU
else
{
PlugMethodAttribute xAttrib = null;
foreach (PlugMethodAttribute attrib in xMethod.GetCustomAttributes(typeof(PlugMethodAttribute), true))
foreach (var x in xMethod.GetReflectionOnlyCustomAttributes<PlugMethodAttribute>(true))
{
xAttrib = attrib;
}
xAttrib = new PlugMethodAttribute
{
Assembler = x.GetArgumentValue<Type>("Assembler"),
Enabled = x.GetArgumentValue<bool>("Enabled"),
IsMicrosoftdotNETOnly = x.GetArgumentValue<bool>("IsMicrosoftdotNETOnly"),
IsMonoOnly = x.GetArgumentValue<bool>("IsMonoOnly"),
IsOptional = x.GetArgumentValue<bool>("IsOptional"),
IsWildcard = x.GetArgumentValue<bool>("IsWildcard"),
PlugRequired = x.GetArgumentValue<bool>("PlugRequired"),
Signature = x.GetArgumentValue<string>("Signature"),
WildcardMatchParameters = x.GetArgumentValue<bool>("WildcardMatchParameters")
};
}
if (xAttrib != null)
{
if (xAttrib.IsWildcard)

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Cosmos.IL2CPU.Plugs;
namespace Cosmos.IL2CPU
{
@ -43,10 +44,13 @@ namespace Cosmos.IL2CPU
PlugMethod = aPlugMethod;
IsInlineAssembler = isInlineAssembler;
Object[] attribs = this.MethodBase.GetCustomAttributes(typeof(Cosmos.IL2CPU.Plugs.DebugStubAttribute), false);
if (attribs.Length > 0)
var attribs = aMethodBase.GetReflectionOnlyCustomAttributes<DebugStubAttribute>(false);
if (attribs.Any())
{
Cosmos.IL2CPU.Plugs.DebugStubAttribute attrib = attribs[0] as Cosmos.IL2CPU.Plugs.DebugStubAttribute;
DebugStubAttribute attrib = new DebugStubAttribute
{
Off = attribs[0].GetArgumentValue<bool>("Off"),
};
DebugStubOff = attrib.Off;
}
}

View file

@ -87,8 +87,9 @@ namespace Cosmos.IL2CPU
// TODO: Allow whole class plugs? ie, a class that completely replaces another class
// and is substituted on the fly? Plug scanner would direct all access to that
// class and throw an exception if any method, field, member etc is missing.
foreach (var xAsm in AppDomain.CurrentDomain.GetAssemblies())
foreach (var xAsm in AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies())
{
// TODO: This will never be true with net core. Remove it?
if (!xAsm.GlobalAssemblyCache)
{
//if (xAsm.GetName().Name == "Cosmos.IL2CPU.X86") {
@ -102,9 +103,9 @@ namespace Cosmos.IL2CPU
foreach (var xPlugType in xAsm.GetTypes())
{
// Foreach, it is possible there could be one plug class with mult plug targets
foreach (PlugAttribute xAttrib in xPlugType.GetCustomAttributes(typeof(PlugAttribute), false))
foreach (var xAttrib in xPlugType.GetCustomAttributesData().Where(x => x.AttributeType.FullName == typeof(PlugAttribute).FullName))
{
var xTargetType = xAttrib.Target;
var xTargetType = xAttrib.GetArgumentValue<Type>("Target");
// If no type is specified, try to find by a specified name.
// This is needed in cross assembly references where the
// plug cannot reference the assembly of the target type
@ -112,11 +113,11 @@ namespace Cosmos.IL2CPU
{
try
{
xTargetType = Type.GetType(xAttrib.TargetName, true, false);
xTargetType = Type.GetType(xAttrib.GetArgumentValue<string>("TargetName"), true, false);
}
catch (Exception ex)
{
if (!xAttrib.IsOptional)
if (!xAttrib.GetArgumentValue<bool>("IsOptional"))
{
throw new Exception("Error", ex);
}
@ -125,16 +126,16 @@ namespace Cosmos.IL2CPU
}
// Only keep this plug if its for MS.NET.
// TODO: Integrate with builder options to allow Mono support again.
if (!xAttrib.IsMonoOnly)
if (!xAttrib.GetArgumentValue<bool>("IsMonoOnly"))
{
Dictionary<Type, List<Type>> mPlugs;
if (xTargetType.ContainsGenericParameters)
{
mPlugs = xAttrib.Inheritable ? mGenericPlugImplsInhrt : mGenericPlugImpls;
mPlugs = xAttrib.GetArgumentValue<bool>("Inheritable") ? mGenericPlugImplsInhrt : mGenericPlugImpls;
}
else
{
mPlugs = xAttrib.Inheritable ? mPlugImplsInhrt : mPlugImpls;
mPlugs = xAttrib.GetArgumentValue<bool>("Inheritable") ? mPlugImplsInhrt : mPlugImpls;
}
List<Type> xImpls;
if (mPlugs.TryGetValue(xTargetType, out xImpls))
@ -172,9 +173,20 @@ namespace Cosmos.IL2CPU
foreach (var xMethod in xImpl.GetMethods(BindingFlags.Public | BindingFlags.Static))
{
PlugMethodAttribute xAttrib = null;
foreach (PlugMethodAttribute x in xMethod.GetCustomAttributes(typeof(PlugMethodAttribute), false))
foreach (var x in xMethod.GetReflectionOnlyCustomAttributes<PlugMethodAttribute>())
{
xAttrib = x;
xAttrib = new PlugMethodAttribute
{
Assembler = x.GetArgumentValue<Type>("Assembler"),
Enabled = x.GetArgumentValue<bool>("Enabled"),
IsMicrosoftdotNETOnly = x.GetArgumentValue<bool>("IsMicrosoftdotNETOnly"),
IsMonoOnly = x.GetArgumentValue<bool>("IsMonoOnly"),
IsOptional = x.GetArgumentValue<bool>("IsOptional"),
IsWildcard = x.GetArgumentValue<bool>("IsWildcard"),
PlugRequired = x.GetArgumentValue<bool>("PlugRequired"),
Signature = x.GetArgumentValue<string>("Signature"),
WildcardMatchParameters = x.GetArgumentValue<bool>("WildcardMatchParameters")
};
}
if (xAttrib == null)
{
@ -195,17 +207,15 @@ namespace Cosmos.IL2CPU
{
// Skip checking methods related to fields because it's just too messy...
// We also skip methods which do method access.
if (xMethod.GetParameters().Where(x =>
{
return x.GetCustomAttributes(typeof(FieldAccessAttribute)).Count() > 0
|| x.GetCustomAttributes(typeof(ObjectPointerAccessAttribute)).Count() > 0;
}).Count() > 0)
if (xMethod.GetParameters().Any(
x => x.GetReflectionOnlyCustomAttributes<FieldAccessAttribute>().Any()
|| x.GetReflectionOnlyCustomAttributes<ObjectPointerAccessAttribute>().Any()))
{
OK = true;
}
else
{
var xParamTypes = xMethod.GetParameters().Select(delegate (ParameterInfo x)
var xParamTypes = xMethod.GetParameters().Select(delegate(ParameterInfo x)
{
var result = x.ParameterType;
if (result.IsByRef)
@ -221,13 +231,13 @@ namespace Cosmos.IL2CPU
var posMethods = xPlug.Key.GetMethods(BindingFlags.Instance | BindingFlags.Static |
BindingFlags.NonPublic | BindingFlags.Public)
.Where(x => x.Name == xMethod.Name);
.Where(x => x.Name == xMethod.Name);
foreach (SysReflection.MethodInfo posInf in posMethods)
{
// If static, no this param
// Otherwise, take into account first param is this param
//This param is either of declaring type, or ref to declaring type or pointer
var posMethParamTypes = posInf.GetParameters().Select(delegate (ParameterInfo x)
var posMethParamTypes = posInf.GetParameters().Select(delegate(ParameterInfo x)
{
var result = x.ParameterType;
if (result.IsByRef)
@ -322,10 +332,7 @@ namespace Cosmos.IL2CPU
if (xAttrib == null
|| xAttrib.IsOptional)
{
if (LogWarning != null)
{
LogWarning("Invalid plug method! Target method not found. : " + xMethod.GetFullName());
}
LogWarning?.Invoke("Invalid plug method! Target method not found. : " + xMethod.GetFullName());
}
}
}
@ -334,28 +341,32 @@ namespace Cosmos.IL2CPU
if (xAttrib.IsWildcard
&& xAttrib.Assembler == null)
{
if (LogWarning != null)
{
LogWarning("Wildcard PlugMethods need to use an assembler for now.");
}
LogWarning?.Invoke("Wildcard PlugMethods need to use an assembler for now.");
}
}
}
#endregion
#region PlugFields scan
foreach (var xField in xImpl.GetCustomAttributes(typeof(PlugFieldAttribute), true).Cast<PlugFieldAttribute>())
foreach (var xField in xImpl.GetReflectionOnlyCustomAttributes<PlugFieldAttribute>(true))
{
var xFieldAttribute = new PlugFieldAttribute();
xFieldAttribute.FieldId = xField.GetArgumentValue<string>("FieldId");
xFieldAttribute.FieldType = xField.GetArgumentValue<Type>("FieldType");
xFieldAttribute.IsExternalValue = xField.GetArgumentValue<bool>("IsExternalValue");
xFieldAttribute.IsMicrosoftdotNETOnly = xField.GetArgumentValue<bool>("IsMicrosoftdotNETOnly");
xFieldAttribute.IsMonoOnly = xField.GetArgumentValue<bool>("IsMonoOnly");
IDictionary<string, PlugFieldAttribute> xFields = null;
if (!mPlugFields.TryGetValue(xPlug.Key, out xFields))
{
xFields = new Dictionary<string, PlugFieldAttribute>();
mPlugFields.Add(xPlug.Key, xFields);
}
if (xFields.ContainsKey(xField.FieldId))
if (xFields.ContainsKey(xField.GetArgumentValue<string>("FieldId")))
{
throw new Exception("Duplicate PlugField found for field '" + xField.FieldId + "'!");
throw new Exception("Duplicate PlugField found for field '" + xField.GetArgumentValue<string>("FieldId") + "'!");
}
xFields.Add(xField.FieldId, xField);
xFields.Add(xField.GetArgumentValue<string>("FieldId"), xFieldAttribute);
}
#endregion
}
@ -417,9 +428,20 @@ namespace Cosmos.IL2CPU
// TODO: Only allow one, but this code for now takes the last one
// if there is more than one
xAttrib = null;
foreach (PlugMethodAttribute x in xSigMethod.GetCustomAttributes(typeof(PlugMethodAttribute), false))
foreach (var x in xSigMethod.GetReflectionOnlyCustomAttributes<PlugMethodAttribute>(false))
{
xAttrib = x;
xAttrib = new PlugMethodAttribute
{
Assembler = x.GetArgumentValue<Type>("Assembler"),
Enabled = x.GetArgumentValue<bool>("Enabled"),
IsMicrosoftdotNETOnly = x.GetArgumentValue<bool>("IsMicrosoftdotNETOnly"),
IsMonoOnly = x.GetArgumentValue<bool>("IsMonoOnly"),
IsOptional = x.GetArgumentValue<bool>("IsOptional"),
IsWildcard = x.GetArgumentValue<bool>("IsWildcard"),
PlugRequired = x.GetArgumentValue<bool>("PlugRequired"),
Signature = x.GetArgumentValue<string>("Signature"),
WildcardMatchParameters = x.GetArgumentValue<bool>("WildcardMatchParameters")
};
}
if (xAttrib != null && (xAttrib.IsWildcard && !xAttrib.WildcardMatchParameters))
@ -458,7 +480,7 @@ namespace Cosmos.IL2CPU
var xActualParamCount = xParams.Length;
foreach (var xParam in xParams)
{
if (xParam.GetCustomAttributes(typeof(FieldAccessAttribute), false).Length > 0)
if (xParam.GetReflectionOnlyCustomAttributes<FieldAccessAttribute>(false).Count > 0)
{
xActualParamCount--;
}
@ -471,11 +493,15 @@ namespace Cosmos.IL2CPU
{
xTypesInst = new Type[0];
var xReplaceType = xParams[0].GetCustomAttributes(typeof(FieldTypeAttribute), false);
if (xReplaceType.Length == 1)
xTypesStatic[0] = Type.GetType(((FieldTypeAttribute)xReplaceType[0]).Name, true);
var xReplaceType = xParams[0].GetReflectionOnlyCustomAttributes<FieldTypeAttribute>(false);
if (xReplaceType.Count == 1)
{
xTypesStatic[0] = Type.GetType(xReplaceType[0].GetArgumentValue<string>("Name"), true);
}
else
{
xTypesStatic[0] = xParams[0].ParameterType;
}
}
else if (xActualParamCount > 1)
{
@ -483,23 +509,27 @@ namespace Cosmos.IL2CPU
var xCurIdx = 0;
foreach (var xParam in xParams.Skip(1))
{
if (xParam.GetCustomAttributes(typeof(FieldAccessAttribute), false).Length > 0)
if (xParam.GetReflectionOnlyCustomAttributes<FieldAccessAttribute>(false).Count > 0)
{
continue;
}
var xReplaceType = xParam.GetCustomAttributes(typeof(FieldTypeAttribute), false);
if (xReplaceType.Length == 1)
xTypesInst[xCurIdx] = Type.GetType(((FieldTypeAttribute)xReplaceType[0]).Name, true);
var xReplaceType = xParam.GetReflectionOnlyCustomAttributes<FieldTypeAttribute>(false);
if (xReplaceType.Count == 1)
{
xTypesInst[xCurIdx] = Type.GetType(xReplaceType[0].GetArgumentValue<string>("Name"), true);
}
else
{
xTypesInst[xCurIdx] = xParam.ParameterType;
}
xCurIdx++;
}
xCurIdx = 0;
foreach (var xParam in xParams)
{
if (xParam.GetCustomAttributes(typeof(FieldAccessAttribute), false).Length > 0)
if (xParam.GetReflectionOnlyCustomAttributes<FieldAccessAttribute>(false).Count > 0)
{
xCurIdx++;
continue;
@ -608,9 +638,20 @@ namespace Cosmos.IL2CPU
{
// TODO: Only allow one, but this code for now takes the last one
// if there is more than one
foreach (PlugMethodAttribute x in xResult.GetCustomAttributes(typeof(PlugMethodAttribute), false))
foreach (var x in xResult.GetReflectionOnlyCustomAttributes<PlugMethodAttribute>(false))
{
xAttrib = x;
xAttrib = new PlugMethodAttribute
{
Assembler = x.GetArgumentValue<Type>("Assembler"),
Enabled = x.GetArgumentValue<bool>("Enabled"),
IsMicrosoftdotNETOnly = x.GetArgumentValue<bool>("IsMicrosoftdotNETOnly"),
IsMonoOnly = x.GetArgumentValue<bool>("IsMonoOnly"),
IsOptional = x.GetArgumentValue<bool>("IsOptional"),
IsWildcard = x.GetArgumentValue<bool>("IsWildcard"),
PlugRequired = x.GetArgumentValue<bool>("PlugRequired"),
Signature = x.GetArgumentValue<string>("Signature"),
WildcardMatchParameters = x.GetArgumentValue<bool>("WildcardMatchParameters")
};
}
}
@ -784,3 +825,4 @@ namespace Cosmos.IL2CPU
}
}
}