Merge some compiler changes from master.

This commit is contained in:
Charles Betros 2016-06-29 23:18:04 -05:00
parent b7cd470c33
commit 37a4e71deb
6 changed files with 156 additions and 227 deletions

View file

@ -22,7 +22,7 @@ namespace Cosmos.TestRunner.Core
// If you're working on the compiler (or other lower parts), you can choose to run the compiler in process // 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! // 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.TraceAssembliesLevel = TraceAssemblies.User;
engine.EnableStackCorruptionChecks = true; engine.EnableStackCorruptionChecks = true;
engine.StackCorruptionChecksLevel = StackCorruptionDetectionLevel.AllInstructions; engine.StackCorruptionChecksLevel = StackCorruptionDetectionLevel.AllInstructions;

View file

@ -337,8 +337,6 @@ namespace Cosmos.IL2CPU
XS.Set(XSRegisters.ECX, 0); XS.Set(XSRegisters.ECX, 0);
var xTotalArgsSize = (from item in aMethod.MethodBase.GetParameters() var xTotalArgsSize = (from item in aMethod.MethodBase.GetParameters()
select (int)ILOp.Align(ILOp.SizeOfType(item.ParameterType), 4)).Sum(); select (int)ILOp.Align(ILOp.SizeOfType(item.ParameterType), 4)).Sum();
if (!aMethod.MethodBase.IsStatic) if (!aMethod.MethodBase.IsStatic)
{ {
if (aMethod.MethodBase.DeclaringType.IsValueType) if (aMethod.MethodBase.DeclaringType.IsValueType)
@ -1271,20 +1269,6 @@ namespace Cosmos.IL2CPU
{ {
xParams = aFrom.MethodBase.GetParameters(); xParams = aFrom.MethodBase.GetParameters();
} }
if (aFrom.MethodBase.Name == "get_Chars")
{
;
}
if (aFrom.MethodBase.Name == "UpdateIDT")
{
;
}
if (aFrom.MethodBase.Name == "get_Length"
&& aFrom.MethodBase.DeclaringType.Name == "Array")
{
;
}
if (ILOp.GetMethodLabel(aFrom) == "SystemVoidSystemActionInvoke") if (ILOp.GetMethodLabel(aFrom) == "SystemVoidSystemActionInvoke")
{ {
; ;

View file

@ -86,10 +86,6 @@ namespace Cosmos.IL2CPU.X86.IL
public static unsafe void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, string nextLabel, bool debugEnabled) public static unsafe void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aCurrent, string currentLabel, string nextLabel, bool debugEnabled)
{ {
if (GetMethodLabel(aTargetMethod) == "SystemStringSystemInt32ToString")
{
;
}
var xMethodInfo = aTargetMethod as SysReflection.MethodInfo; var xMethodInfo = aTargetMethod as SysReflection.MethodInfo;
// mTargetMethodInfo = GetService<IMetaDataInfoService>().GetMethodInfo(mMethod // mTargetMethodInfo = GetService<IMetaDataInfoService>().GetMethodInfo(mMethod

View file

@ -9,7 +9,6 @@ using Cosmos.IL2CPU.Plugs;
using SR = System.Reflection; using SR = System.Reflection;
using SysReflection = System.Reflection; using SysReflection = System.Reflection;
namespace Cosmos.IL2CPU namespace Cosmos.IL2CPU
{ {
public delegate void LogExceptionDelegate(Exception e); public delegate void LogExceptionDelegate(Exception e);
@ -17,8 +16,8 @@ namespace Cosmos.IL2CPU
public class ScannerQueueItem public class ScannerQueueItem
{ {
public _MemberInfo Item; public _MemberInfo Item;
public string QueueReason;
public string SourceItem; public string SourceItem;
public string QueueReason;
public override string ToString() public override string ToString()
{ {
@ -30,37 +29,41 @@ namespace Cosmos.IL2CPU
{ {
public LogExceptionDelegate LogException = null; public LogExceptionDelegate LogException = null;
public Action<string> LogWarning = null; public Action<string> LogWarning = null;
protected AppAssembler mAsmblr;
protected OurHashSet<_MemberInfo> mItems = new OurHashSet<_MemberInfo>();
protected List<object> mItemsList = new List<object>();
// Logging
// Only use for debugging and profiling.
protected bool mLogEnabled;
protected Dictionary<object, List<LogItem>> mLogMap;
protected TextWriter mLogWriter;
protected string mMapPathname;
protected IDictionary<MethodBase, uint> mMethodUIDs = new Dictionary<MethodBase, uint>();
protected PlugManager mPlugManager;
// Contains items to be scanned, both types and methods
protected Queue<ScannerQueueItem> mQueue = new Queue<ScannerQueueItem>();
protected ILReader mReader; protected ILReader mReader;
protected IDictionary<Type, uint> mTypeUIDs = new Dictionary<Type, uint>(); protected AppAssembler mAsmblr;
// List of asssemblies found during scan. We cannot use the list of loaded // List of asssemblies found during scan. We cannot use the list of loaded
// assemblies because the loaded list includes compilers, etc, and also possibly // assemblies because the loaded list includes compilers, etc, and also possibly
// other unused assemblies. So instead we collect a list of assemblies as we scan. // other unused assemblies. So instead we collect a list of assemblies as we scan.
internal List<Assembly> mUsedAssemblies = new List<Assembly>(); internal List<Assembly> mUsedAssemblies = new List<Assembly>();
protected OurHashSet<_MemberInfo> mItems = new OurHashSet<_MemberInfo>();
protected List<object> mItemsList = new List<object>();
// Contains items to be scanned, both types and methods
protected Queue<ScannerQueueItem> mQueue = new Queue<ScannerQueueItem>();
// Virtual methods are nasty and constantly need to be rescanned for // Virtual methods are nasty and constantly need to be rescanned for
// overriding methods in new types, so we keep track of them separately. // overriding methods in new types, so we keep track of them separately.
// They are also in the main mItems and mQueue. // They are also in the main mItems and mQueue.
protected HashSet<MethodBase> mVirtuals = new HashSet<MethodBase>(); protected HashSet<MethodBase> mVirtuals = new HashSet<MethodBase>();
protected IDictionary<MethodBase, uint> mMethodUIDs = new Dictionary<MethodBase, uint>();
protected IDictionary<Type, uint> mTypeUIDs = new Dictionary<Type, uint>();
protected PlugManager mPlugManager = null;
// Logging
// Only use for debugging and profiling.
protected bool mLogEnabled = false;
protected string mMapPathname;
protected TextWriter mLogWriter;
protected struct LogItem
{
public string SrcType;
public object Item;
}
protected Dictionary<object, List<LogItem>> mLogMap;
public ILScanner(AppAssembler aAsmblr) public ILScanner(AppAssembler aAsmblr)
{ {
mAsmblr = aAsmblr; mAsmblr = aAsmblr;
@ -69,90 +72,6 @@ namespace Cosmos.IL2CPU
mPlugManager = new PlugManager(LogException, LogWarning); mPlugManager = new PlugManager(LogException, LogWarning);
} }
public int MethodCount
{
get
{
return mMethodUIDs.Count;
}
}
public void Dispose()
{
if (mLogEnabled)
{
// Create bookmarks, but also a dictionary that
// we can find the items in
var xBookmarks = new Dictionary<object, int>();
int xBookmark = 0;
foreach (var xList in mLogMap)
{
foreach (var xItem in xList.Value)
{
xBookmarks.Add(xItem.Item, xBookmark);
xBookmark++;
}
}
using (mLogWriter = new StreamWriter(mMapPathname, false))
{
mLogWriter.WriteLine("<html><body>");
foreach (var xList in mLogMap)
{
var xLogItemText = LogItemText(xList.Key);
mLogWriter.WriteLine("<hr>");
// Emit bookmarks above source, so when clicking links user doesn't need
// to constantly scroll up.
foreach (var xItem in xList.Value)
{
mLogWriter.WriteLine("<a name=\"Item" + xBookmarks[xItem.Item] + "_S\"></a>");
}
int xHref;
if (!xBookmarks.TryGetValue(xList.Key, out xHref))
{
xHref = -1;
}
mLogWriter.Write("<p>");
if (xHref >= 0)
{
mLogWriter.WriteLine("<a href=\"#Item" + xHref + "_S\">");
mLogWriter.WriteLine("<a name=\"Item{0}\">", xHref);
}
if (xList.Key == null)
{
mLogWriter.WriteLine("Unspecified Source");
}
else
{
mLogWriter.WriteLine(xLogItemText);
}
if (xHref >= 0)
{
mLogWriter.Write("</a>");
mLogWriter.Write("</a>");
}
mLogWriter.WriteLine("</p>");
mLogWriter.WriteLine("<ul>");
foreach (var xItem in xList.Value)
{
mLogWriter.Write("<li><a href=\"#Item{1}\">{0}</a></li>", LogItemText(xItem.Item),
xBookmarks[xItem.Item]);
mLogWriter.WriteLine("<ul>");
mLogWriter.WriteLine("<li>" + xItem.SrcType + "</li>");
mLogWriter.WriteLine("</ul>");
}
mLogWriter.WriteLine("</ul>");
}
mLogWriter.WriteLine("</body></html>");
}
}
}
public bool EnableLogging(string aPathname) public bool EnableLogging(string aPathname)
{ {
mLogMap = new Dictionary<object, List<LogItem>>(); mLogMap = new Dictionary<object, List<LogItem>>();
@ -219,12 +138,7 @@ namespace Cosmos.IL2CPU
aSrc = methodBaseSource.DeclaringType + "::" + aSrc; aSrc = methodBaseSource.DeclaringType + "::" + aSrc;
} }
mQueue.Enqueue(new ScannerQueueItem mQueue.Enqueue(new ScannerQueueItem { Item = aItem, QueueReason = aSrcType, SourceItem = aSrc + Environment.NewLine + sourceItem });
{
Item = aItem,
QueueReason = aSrcType,
SourceItem = aSrc + Environment.NewLine + sourceItem
});
} }
} }
@ -239,7 +153,6 @@ namespace Cosmos.IL2CPU
// http://cciast.codeplex.com/ // http://cciast.codeplex.com/
#region Description #region Description
// Methodology // Methodology
// //
// Ok - we've done the scanner enough times to know it needs to be // Ok - we've done the scanner enough times to know it needs to be
@ -283,7 +196,6 @@ namespace Cosmos.IL2CPU
// -Known Types and Methods // -Known Types and Methods
// -Types and Methods in Queue - to be scanned // -Types and Methods in Queue - to be scanned
// -Finally, do compilation // -Finally, do compilation
#endregion #endregion
mPlugManager.FindPlugImpls(); mPlugManager.FindPlugImpls();
@ -310,24 +222,16 @@ namespace Cosmos.IL2CPU
Queue(GCImplementationRefs.DecRefCountRef, null, "Explicit Entry"); Queue(GCImplementationRefs.DecRefCountRef, null, "Explicit Entry");
Queue(GCImplementationRefs.AllocNewObjectRef, null, "Explicit Entry"); Queue(GCImplementationRefs.AllocNewObjectRef, null, "Explicit Entry");
// for now, to ease runtime exception throwing // for now, to ease runtime exception throwing
Queue( Queue(typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public, null, new Type[] {typeof(string)}, null), null, "Explicit Entry");
typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public, null, Queue(typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public, null, new Type[] {}, null), null, "Explicit Entry");
new[] {typeof(string)}, null), null, "Explicit Entry");
Queue(
typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public, null,
new Type[] {}, null), null, "Explicit Entry");
Queue(RuntimeEngineRefs.InitializeApplicationRef, null, "Explicit Entry"); Queue(RuntimeEngineRefs.InitializeApplicationRef, null, "Explicit Entry");
Queue(RuntimeEngineRefs.FinalizeApplicationRef, null, "Explicit Entry"); Queue(RuntimeEngineRefs.FinalizeApplicationRef, null, "Explicit Entry");
// register system types: // register system types:
Queue(typeof(Array), null, "Explicit Entry"); Queue(typeof(Array), null, "Explicit Entry");
Queue( Queue(typeof(Array).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null), null, "Explicit Entry");
typeof(Array).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null),
null, "Explicit Entry");
var xThrowHelper = Type.GetType("System.ThrowHelper", true); var xThrowHelper = Type.GetType("System.ThrowHelper", true);
Queue( Queue(xThrowHelper.GetMethod("ThrowInvalidOperationException", BindingFlags.NonPublic | BindingFlags.Static), null, "Explicit Entry");
xThrowHelper.GetMethod("ThrowInvalidOperationException", BindingFlags.NonPublic | BindingFlags.Static),
null, "Explicit Entry");
Queue(typeof(MulticastDelegate).GetMethod("GetInvocationList"), null, "Explicit Entry"); Queue(typeof(MulticastDelegate).GetMethod("GetInvocationList"), null, "Explicit Entry");
Queue(ExceptionHelperRefs.CurrentExceptionRef, null, "Explicit Entry"); Queue(ExceptionHelperRefs.CurrentExceptionRef, null, "Explicit Entry");
@ -358,12 +262,95 @@ namespace Cosmos.IL2CPU
if (xOpMethod != null) if (xOpMethod != null)
{ {
xOpMethod.Value = (MethodBase) mItems.GetItemInList(xOpMethod.Value); xOpMethod.Value = (MethodBase) mItems.GetItemInList(xOpMethod.Value);
xOpMethod.ValueUID = GetMethodUID(xOpMethod.Value, true); xOpMethod.ValueUID = (uint)GetMethodUID(xOpMethod.Value, true);
xOpMethod.BaseMethodUID = GetMethodUID(xOpMethod.Value, false); xOpMethod.BaseMethodUID = GetMethodUID(xOpMethod.Value, false);
} }
} }
} }
public void Dispose()
{
if (mLogEnabled)
{
// Create bookmarks, but also a dictionary that
// we can find the items in
var xBookmarks = new Dictionary<object, int>();
int xBookmark = 0;
foreach (var xList in mLogMap)
{
foreach (var xItem in xList.Value)
{
xBookmarks.Add(xItem.Item, xBookmark);
xBookmark++;
}
}
using (mLogWriter = new StreamWriter(mMapPathname, false))
{
mLogWriter.WriteLine("<html><body>");
foreach (var xList in mLogMap)
{
var xLogItemText = LogItemText(xList.Key);
mLogWriter.WriteLine("<hr>");
// Emit bookmarks above source, so when clicking links user doesn't need
// to constantly scroll up.
foreach (var xItem in xList.Value)
{
mLogWriter.WriteLine("<a name=\"Item" + xBookmarks[xItem.Item].ToString() + "_S\"></a>");
}
int xHref;
if (!xBookmarks.TryGetValue(xList.Key, out xHref))
{
xHref = -1;
}
mLogWriter.Write("<p>");
if (xHref >= 0)
{
mLogWriter.WriteLine("<a href=\"#Item" + xHref.ToString() + "_S\">");
mLogWriter.WriteLine("<a name=\"Item{0}\">", xHref);
}
if (xList.Key == null)
{
mLogWriter.WriteLine("Unspecified Source");
}
else
{
mLogWriter.WriteLine(xLogItemText);
}
if (xHref >= 0)
{
mLogWriter.Write("</a>");
mLogWriter.Write("</a>");
}
mLogWriter.WriteLine("</p>");
mLogWriter.WriteLine("<ul>");
foreach (var xItem in xList.Value)
{
mLogWriter.Write("<li><a href=\"#Item{1}\">{0}</a></li>", LogItemText(xItem.Item), xBookmarks[xItem.Item]);
mLogWriter.WriteLine("<ul>");
mLogWriter.WriteLine("<li>" + xItem.SrcType + "</li>");
mLogWriter.WriteLine("</ul>");
}
mLogWriter.WriteLine("</ul>");
}
mLogWriter.WriteLine("</body></html>");
}
}
}
public int MethodCount
{
get
{
return mMethodUIDs.Count;
}
}
protected string LogItemText(object aItem) protected string LogItemText(object aItem)
{ {
if (aItem is MethodBase) if (aItem is MethodBase)
@ -412,9 +399,7 @@ namespace Cosmos.IL2CPU
; ;
} }
// Scan virtuals // Scan virtuals
#region Virtuals scan #region Virtuals scan
if (!xIsDynamicMethod && aMethod.IsVirtual) if (!xIsDynamicMethod && aMethod.IsVirtual)
{ {
// For virtuals we need to climb up the type tree // For virtuals we need to climb up the type tree
@ -436,9 +421,7 @@ namespace Cosmos.IL2CPU
} }
else else
{ {
xNewVirtMethod = xVirtType.GetMethod(aMethod.Name, xNewVirtMethod = xVirtType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, null);
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes,
null);
if (xNewVirtMethod != null) if (xNewVirtMethod != null)
{ {
if (!xNewVirtMethod.IsVirtual) if (!xNewVirtMethod.IsVirtual)
@ -478,13 +461,9 @@ namespace Cosmos.IL2CPU
if (mItemsList[i] is Type) if (mItemsList[i] is Type)
{ {
var xType = (Type) mItemsList[i]; var xType = (Type) mItemsList[i];
if (xType.IsSubclassOf(xVirtMethod.DeclaringType) || if (xType.IsSubclassOf(xVirtMethod.DeclaringType) || (xVirtMethod.DeclaringType.IsInterface && xVirtMethod.DeclaringType.IsAssignableFrom(xType)))
(xVirtMethod.DeclaringType.IsInterface &&
xVirtMethod.DeclaringType.IsAssignableFrom(xType)))
{ {
var xNewMethod = xType.GetMethod(aMethod.Name, var xNewMethod = xType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, null);
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null,
xParamTypes, null);
if (xNewMethod != null) if (xNewMethod != null)
{ {
// We need to check IsVirtual, a non virtual could // We need to check IsVirtual, a non virtual could
@ -499,7 +478,6 @@ namespace Cosmos.IL2CPU
} }
} }
} }
#endregion #endregion
MethodBase xPlug = null; MethodBase xPlug = null;
@ -541,10 +519,7 @@ namespace Cosmos.IL2CPU
} }
if (xNeedsPlug) if (xNeedsPlug)
{ {
throw new Exception( throw new Exception("Native code encountered, plug required. Please see https://github.com/CosmosOS/Cosmos/wiki/Plugs). " + LabelName.GenerateFullName(aMethod) + "." + Environment.NewLine + " Called from :" + Environment.NewLine + sourceItem);
"Native code encountered, plug required. Please see https://github.com/CosmosOS/Cosmos/wiki/Plugs). " +
LabelName.GenerateFullName(aMethod) + "." + Environment.NewLine + " Called from :" +
Environment.NewLine + sourceItem);
} }
//TODO: As we scan each method, we could update or put in a new list //TODO: As we scan each method, we could update or put in a new list
@ -622,8 +597,7 @@ namespace Cosmos.IL2CPU
// Queue static ctors // Queue static ctors
// We always need static ctors, else the type cannot // We always need static ctors, else the type cannot
// be created. // be created.
foreach ( foreach (var xCctor in aType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
var xCctor in aType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public))
{ {
if (xCctor.DeclaringType == aType) if (xCctor.DeclaringType == aType)
{ {
@ -770,11 +744,7 @@ namespace Cosmos.IL2CPU
{ {
xBaseMethod = xFoundMethod; xBaseMethod = xFoundMethod;
if ((xFoundMethod.IsVirtual == aMethod.IsVirtual) && (xFoundMethod.IsPrivate == false) && if ((xFoundMethod.IsVirtual == aMethod.IsVirtual) && (xFoundMethod.IsPrivate == false) && (xFoundMethod.IsPublic == aMethod.IsPublic) && (xFoundMethod.IsFamily == aMethod.IsFamily) && (xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly) && (xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly) && (xFoundMethod.IsFinal == false))
(xFoundMethod.IsPublic == aMethod.IsPublic) && (xFoundMethod.IsFamily == aMethod.IsFamily) &&
(xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly) &&
(xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly) &&
(xFoundMethod.IsFinal == false))
{ {
var xFoundMethInfo = xFoundMethod as SR.MethodInfo; var xFoundMethInfo = xFoundMethod as SR.MethodInfo;
var xBaseMethInfo = xBaseMethod as SR.MethodInfo; var xBaseMethInfo = xBaseMethod as SR.MethodInfo;
@ -858,8 +828,6 @@ namespace Cosmos.IL2CPU
foreach (var xItem in mItems) foreach (var xItem in mItems)
{ {
if (xItem is MethodBase) if (xItem is MethodBase)
{
try
{ {
var xMethod = (MethodBase) xItem; var xMethod = (MethodBase) xItem;
var xParams = xMethod.GetParameters(); var xParams = xMethod.GetParameters();
@ -968,23 +936,10 @@ namespace Cosmos.IL2CPU
} }
} }
} }
catch (Exception E) else if (xItem is FieldInfo)
{
throw new Exception("An error occurred while assembling method '" + ((MethodBase) xItem).GetFullName() + "'", E);
}
continue;
}
if (xItem is FieldInfo)
{
try
{ {
mAsmblr.ProcessField((FieldInfo) xItem); mAsmblr.ProcessField((FieldInfo) xItem);
} }
catch (Exception E)
{
throw new Exception("Error occurred while assembling field '" + ((FieldInfo) xItem).GetFullName() + "'", E);
}
}
} }
var xTypes = new HashSet<Type>(); var xTypes = new HashSet<Type>();
@ -1002,11 +957,5 @@ namespace Cosmos.IL2CPU
} }
mAsmblr.GenerateVMTCode(xTypes, xMethods, GetTypeUID, x => GetMethodUID(x, false)); mAsmblr.GenerateVMTCode(xTypes, xMethods, GetTypeUID, x => GetMethodUID(x, false));
} }
protected struct LogItem
{
public string SrcType;
public object Item;
}
} }
} }