From 37a4e71deb6ca230ef68af8d1ccf11fd26f1c352 Mon Sep 17 00:00:00 2001 From: Charles Betros Date: Wed, 29 Jun 2016 23:18:04 -0500 Subject: [PATCH] Merge some compiler changes from master. --- .../DefaultEngineConfiguration.cs | 2 +- source/Cosmos.IL2CPU/AppAssembler.cs | 16 - source/Cosmos.IL2CPU/IL/Call.cs | 4 - source/Cosmos.IL2CPU/ILScanner.cs | 291 ++++++++---------- .../CompilerServices/RuntimeHelpersImpl.cs | 68 ++-- .../Compilerservices/runtimehelpersImpl.cs | 2 +- 6 files changed, 156 insertions(+), 227 deletions(-) diff --git a/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs b/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs index 0163830c3..2d52a8038 100644 --- a/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs +++ b/Tests/Cosmos.TestRunner.Core/DefaultEngineConfiguration.cs @@ -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 // 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; diff --git a/source/Cosmos.IL2CPU/AppAssembler.cs b/source/Cosmos.IL2CPU/AppAssembler.cs index c67181226..3cb740625 100644 --- a/source/Cosmos.IL2CPU/AppAssembler.cs +++ b/source/Cosmos.IL2CPU/AppAssembler.cs @@ -337,8 +337,6 @@ namespace Cosmos.IL2CPU XS.Set(XSRegisters.ECX, 0); var xTotalArgsSize = (from item in aMethod.MethodBase.GetParameters() select (int)ILOp.Align(ILOp.SizeOfType(item.ParameterType), 4)).Sum(); - - if (!aMethod.MethodBase.IsStatic) { if (aMethod.MethodBase.DeclaringType.IsValueType) @@ -1271,20 +1269,6 @@ namespace Cosmos.IL2CPU { 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") { ; diff --git a/source/Cosmos.IL2CPU/IL/Call.cs b/source/Cosmos.IL2CPU/IL/Call.cs index 9b0912651..66f4a58af 100644 --- a/source/Cosmos.IL2CPU/IL/Call.cs +++ b/source/Cosmos.IL2CPU/IL/Call.cs @@ -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) { - if (GetMethodLabel(aTargetMethod) == "SystemStringSystemInt32ToString") - { - ; - } var xMethodInfo = aTargetMethod as SysReflection.MethodInfo; // mTargetMethodInfo = GetService().GetMethodInfo(mMethod diff --git a/source/Cosmos.IL2CPU/ILScanner.cs b/source/Cosmos.IL2CPU/ILScanner.cs index 71cd036c6..1d1abfeab 100644 --- a/source/Cosmos.IL2CPU/ILScanner.cs +++ b/source/Cosmos.IL2CPU/ILScanner.cs @@ -9,7 +9,6 @@ using Cosmos.IL2CPU.Plugs; using SR = System.Reflection; using SysReflection = System.Reflection; - namespace Cosmos.IL2CPU { public delegate void LogExceptionDelegate(Exception e); @@ -17,8 +16,8 @@ namespace Cosmos.IL2CPU public class ScannerQueueItem { public _MemberInfo Item; - public string QueueReason; public string SourceItem; + public string QueueReason; public override string ToString() { @@ -30,37 +29,41 @@ namespace Cosmos.IL2CPU { public LogExceptionDelegate LogException = null; public Action LogWarning = null; - protected AppAssembler mAsmblr; - - protected OurHashSet<_MemberInfo> mItems = new OurHashSet<_MemberInfo>(); - protected List mItemsList = new List(); - - // Logging - // Only use for debugging and profiling. - protected bool mLogEnabled; - - protected Dictionary> mLogMap; - protected TextWriter mLogWriter; - protected string mMapPathname; - - protected IDictionary mMethodUIDs = new Dictionary(); - - protected PlugManager mPlugManager; - // Contains items to be scanned, both types and methods - protected Queue mQueue = new Queue(); protected ILReader mReader; - protected IDictionary mTypeUIDs = new Dictionary(); + protected AppAssembler mAsmblr; // List of asssemblies found during scan. We cannot use the list of loaded // 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. internal List mUsedAssemblies = new List(); + + protected OurHashSet<_MemberInfo> mItems = new OurHashSet<_MemberInfo>(); + protected List mItemsList = new List(); + // Contains items to be scanned, both types and methods + protected Queue mQueue = new Queue(); // Virtual methods are nasty and constantly need to be rescanned for // overriding methods in new types, so we keep track of them separately. // They are also in the main mItems and mQueue. protected HashSet mVirtuals = new HashSet(); + protected IDictionary mMethodUIDs = new Dictionary(); + protected IDictionary mTypeUIDs = new Dictionary(); + + 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> mLogMap; + public ILScanner(AppAssembler aAsmblr) { mAsmblr = aAsmblr; @@ -69,90 +72,6 @@ namespace Cosmos.IL2CPU 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(); - 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(""); - foreach (var xList in mLogMap) - { - var xLogItemText = LogItemText(xList.Key); - - mLogWriter.WriteLine("
"); - - // Emit bookmarks above source, so when clicking links user doesn't need - // to constantly scroll up. - foreach (var xItem in xList.Value) - { - mLogWriter.WriteLine(""); - } - - int xHref; - if (!xBookmarks.TryGetValue(xList.Key, out xHref)) - { - xHref = -1; - } - mLogWriter.Write("

"); - if (xHref >= 0) - { - mLogWriter.WriteLine(""); - mLogWriter.WriteLine("", xHref); - } - if (xList.Key == null) - { - mLogWriter.WriteLine("Unspecified Source"); - } - else - { - mLogWriter.WriteLine(xLogItemText); - } - if (xHref >= 0) - { - mLogWriter.Write(""); - mLogWriter.Write(""); - } - mLogWriter.WriteLine("

"); - - mLogWriter.WriteLine("
    "); - foreach (var xItem in xList.Value) - { - mLogWriter.Write("
  • {0}
  • ", LogItemText(xItem.Item), - xBookmarks[xItem.Item]); - - mLogWriter.WriteLine("
      "); - mLogWriter.WriteLine("
    • " + xItem.SrcType + "
    • "); - mLogWriter.WriteLine("
    "); - } - mLogWriter.WriteLine("
"); - } - mLogWriter.WriteLine(""); - } - } - } - public bool EnableLogging(string aPathname) { mLogMap = new Dictionary>(); @@ -219,12 +138,7 @@ namespace Cosmos.IL2CPU aSrc = methodBaseSource.DeclaringType + "::" + aSrc; } - mQueue.Enqueue(new ScannerQueueItem - { - Item = aItem, - QueueReason = aSrcType, - SourceItem = aSrc + Environment.NewLine + sourceItem - }); + mQueue.Enqueue(new ScannerQueueItem { Item = aItem, QueueReason = aSrcType, SourceItem = aSrc + Environment.NewLine + sourceItem }); } } @@ -239,7 +153,6 @@ namespace Cosmos.IL2CPU // http://cciast.codeplex.com/ #region Description - // Methodology // // 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 // -Types and Methods in Queue - to be scanned // -Finally, do compilation - #endregion mPlugManager.FindPlugImpls(); @@ -310,24 +222,16 @@ namespace Cosmos.IL2CPU Queue(GCImplementationRefs.DecRefCountRef, null, "Explicit Entry"); Queue(GCImplementationRefs.AllocNewObjectRef, null, "Explicit Entry"); // for now, to ease runtime exception throwing - Queue( - typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public, null, - new[] {typeof(string)}, null), null, "Explicit Entry"); - Queue( - typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public, null, - new Type[] {}, null), null, "Explicit Entry"); + Queue(typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public, null, new Type[] {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.FinalizeApplicationRef, null, "Explicit Entry"); // register system types: Queue(typeof(Array), null, "Explicit Entry"); - Queue( - typeof(Array).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null), - null, "Explicit Entry"); + Queue(typeof(Array).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null), null, "Explicit Entry"); var xThrowHelper = Type.GetType("System.ThrowHelper", true); - Queue( - xThrowHelper.GetMethod("ThrowInvalidOperationException", BindingFlags.NonPublic | BindingFlags.Static), - null, "Explicit Entry"); + Queue(xThrowHelper.GetMethod("ThrowInvalidOperationException", BindingFlags.NonPublic | BindingFlags.Static), null, "Explicit Entry"); Queue(typeof(MulticastDelegate).GetMethod("GetInvocationList"), null, "Explicit Entry"); Queue(ExceptionHelperRefs.CurrentExceptionRef, null, "Explicit Entry"); @@ -358,12 +262,95 @@ namespace Cosmos.IL2CPU if (xOpMethod != null) { 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); } } } + public void Dispose() + { + if (mLogEnabled) + { + // Create bookmarks, but also a dictionary that + // we can find the items in + var xBookmarks = new Dictionary(); + 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(""); + foreach (var xList in mLogMap) + { + var xLogItemText = LogItemText(xList.Key); + + mLogWriter.WriteLine("
"); + + // Emit bookmarks above source, so when clicking links user doesn't need + // to constantly scroll up. + foreach (var xItem in xList.Value) + { + mLogWriter.WriteLine(""); + } + + int xHref; + if (!xBookmarks.TryGetValue(xList.Key, out xHref)) + { + xHref = -1; + } + mLogWriter.Write("

"); + if (xHref >= 0) + { + mLogWriter.WriteLine(""); + mLogWriter.WriteLine("", xHref); + } + if (xList.Key == null) + { + mLogWriter.WriteLine("Unspecified Source"); + } + else + { + mLogWriter.WriteLine(xLogItemText); + } + if (xHref >= 0) + { + mLogWriter.Write(""); + mLogWriter.Write(""); + } + mLogWriter.WriteLine("

"); + + mLogWriter.WriteLine("
    "); + foreach (var xItem in xList.Value) + { + mLogWriter.Write("
  • {0}
  • ", LogItemText(xItem.Item), xBookmarks[xItem.Item]); + + mLogWriter.WriteLine("
      "); + mLogWriter.WriteLine("
    • " + xItem.SrcType + "
    • "); + mLogWriter.WriteLine("
    "); + } + mLogWriter.WriteLine("
"); + } + mLogWriter.WriteLine(""); + } + } + } + + public int MethodCount + { + get + { + return mMethodUIDs.Count; + } + } + protected string LogItemText(object aItem) { if (aItem is MethodBase) @@ -412,9 +399,7 @@ namespace Cosmos.IL2CPU ; } // Scan virtuals - #region Virtuals scan - if (!xIsDynamicMethod && aMethod.IsVirtual) { // For virtuals we need to climb up the type tree @@ -436,9 +421,7 @@ namespace Cosmos.IL2CPU } else { - xNewVirtMethod = xVirtType.GetMethod(aMethod.Name, - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, - null); + xNewVirtMethod = xVirtType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, null); if (xNewVirtMethod != null) { if (!xNewVirtMethod.IsVirtual) @@ -478,13 +461,9 @@ namespace Cosmos.IL2CPU if (mItemsList[i] is Type) { var xType = (Type) mItemsList[i]; - if (xType.IsSubclassOf(xVirtMethod.DeclaringType) || - (xVirtMethod.DeclaringType.IsInterface && - xVirtMethod.DeclaringType.IsAssignableFrom(xType))) + if (xType.IsSubclassOf(xVirtMethod.DeclaringType) || (xVirtMethod.DeclaringType.IsInterface && xVirtMethod.DeclaringType.IsAssignableFrom(xType))) { - var xNewMethod = xType.GetMethod(aMethod.Name, - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, - xParamTypes, null); + var xNewMethod = xType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, xParamTypes, null); if (xNewMethod != null) { // We need to check IsVirtual, a non virtual could @@ -499,7 +478,6 @@ namespace Cosmos.IL2CPU } } } - #endregion MethodBase xPlug = null; @@ -541,10 +519,7 @@ namespace Cosmos.IL2CPU } if (xNeedsPlug) { - 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); + 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); } //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 // We always need static ctors, else the type cannot // be created. - foreach ( - var xCctor in aType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) + foreach (var xCctor in aType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)) { if (xCctor.DeclaringType == aType) { @@ -770,11 +744,7 @@ namespace Cosmos.IL2CPU { xBaseMethod = xFoundMethod; - 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)) + 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)) { var xFoundMethInfo = xFoundMethod as SR.MethodInfo; var xBaseMethInfo = xBaseMethod as SR.MethodInfo; @@ -859,8 +829,6 @@ namespace Cosmos.IL2CPU { if (xItem is MethodBase) { - try - { var xMethod = (MethodBase) xItem; var xParams = xMethod.GetParameters(); var xParamTypes = xParams.Select(q => q.ParameterType).ToArray(); @@ -968,22 +936,9 @@ namespace Cosmos.IL2CPU } } } - catch (Exception E) - { - throw new Exception("An error occurred while assembling method '" + ((MethodBase) xItem).GetFullName() + "'", E); - } - continue; - } - if (xItem is FieldInfo) + else if (xItem is FieldInfo) { - try - { mAsmblr.ProcessField((FieldInfo) xItem); - } - catch (Exception E) - { - throw new Exception("Error occurred while assembling field '" + ((FieldInfo) xItem).GetFullName() + "'", E); - } } } @@ -1002,11 +957,5 @@ namespace Cosmos.IL2CPU } mAsmblr.GenerateVMTCode(xTypes, xMethods, GetTypeUID, x => GetMethodUID(x, false)); } - - protected struct LogItem - { - public string SrcType; - public object Item; - } } } diff --git a/source/Cosmos.IL2CPU/Plugs/System/Runtime/CompilerServices/RuntimeHelpersImpl.cs b/source/Cosmos.IL2CPU/Plugs/System/Runtime/CompilerServices/RuntimeHelpersImpl.cs index 61c22b0b4..f6a5ff621 100644 --- a/source/Cosmos.IL2CPU/Plugs/System/Runtime/CompilerServices/RuntimeHelpersImpl.cs +++ b/source/Cosmos.IL2CPU/Plugs/System/Runtime/CompilerServices/RuntimeHelpersImpl.cs @@ -6,56 +6,56 @@ using static XSharp.Compiler.XSRegisters; using CPUx86 = Cosmos.Assembler.x86; namespace Cosmos.IL2CPU.Plugs.System.Runtime.CompilerServices { - [Plug(Target = typeof(global::System.Runtime.CompilerServices.RuntimeHelpers))] - public static class RuntimeHelpersImpl { + [Plug(Target = typeof(global::System.Runtime.CompilerServices.RuntimeHelpers))] + public static class RuntimeHelpersImpl { - public static void cctor() { - //TODO: do something - } + 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); - } + 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)] + [Inline(TargetPlatform = TargetPlatform.x86)] [PlugMethod] - public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle) { - // Arguments: - // Array aArray, RuntimeFieldHandle aFieldHandle + public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle) { + // Arguments: + // Array aArray, RuntimeFieldHandle aFieldHandle XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 20); // array - XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: 12);// aFieldHandle + XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: 12); // aFieldHandle XS.Add(XSRegisters.EDI, 8); - XS.Push(EDI, isIndirect: true); + XS.Push(EDI, isIndirect: true); XS.Add(XSRegisters.EDI, 4); XS.Set(EAX, EDI, sourceIsIndirect: true); - XS.Multiply(ESP, isIndirect: true, size: RegisterSize.Int32); + XS.Multiply(ESP, isIndirect: true, size: RegisterSize.Int32); XS.Pop(XSRegisters.ECX); XS.Set(XSRegisters.ECX, XSRegisters.EAX); XS.Set(XSRegisters.EAX, 0); XS.Add(XSRegisters.EDI, 4); - XS.Label(".StartLoop"); - XS.Set(DL, ESI, sourceIsIndirect: true); + XS.Label(".StartLoop"); + XS.Set(DL, ESI, sourceIsIndirect: true); XS.Set(EDI, DL, destinationIsIndirect: true); - XS.Add(XSRegisters.EAX, 1); + XS.Add(XSRegisters.EAX, 1); XS.Add(XSRegisters.ESI, 1); XS.Add(XSRegisters.EDI, 1); - XS.Compare(XSRegisters.EAX, XSRegisters.ECX); + XS.Compare(XSRegisters.EAX, XSRegisters.ECX); XS.Jump(CPUx86.ConditionalTestEnum.Equal, ".EndLoop"); XS.Jump(".StartLoop"); - XS.Label(".EndLoop"); - } - } -} + XS.Label(".EndLoop"); + } + } +} \ No newline at end of file diff --git a/source/Cosmos.System.Plugs/System/Runtime/Compilerservices/runtimehelpersImpl.cs b/source/Cosmos.System.Plugs/System/Runtime/Compilerservices/runtimehelpersImpl.cs index e9af397fd..db4d6acb8 100644 --- a/source/Cosmos.System.Plugs/System/Runtime/Compilerservices/runtimehelpersImpl.cs +++ b/source/Cosmos.System.Plugs/System/Runtime/Compilerservices/runtimehelpersImpl.cs @@ -14,4 +14,4 @@ namespace Cosmos.System.Plugs.System.Runtime.Compilerservices throw new NotImplementedException("runtimehelpersImpl.GetHashCode()"); } } -} +} \ No newline at end of file