diff --git a/src/Common/src/Internal/Text/Utf8StringBuilder.cs b/src/Common/src/Internal/Text/Utf8StringBuilder.cs index 61a124303f2..1fcca945075 100644 --- a/src/Common/src/Internal/Text/Utf8StringBuilder.cs +++ b/src/Common/src/Internal/Text/Utf8StringBuilder.cs @@ -4,6 +4,7 @@ using System; using System.Text; +using System.Diagnostics; namespace Internal.Text { @@ -26,6 +27,13 @@ public Utf8StringBuilder Clear() return this; } + public Utf8StringBuilder Truncate(int newLength) + { + Debug.Assert(newLength <= _length); + _length = newLength; + return this; + } + public Utf8StringBuilder Append(Utf8String value) { return Append(value.UnderlyingArray); diff --git a/src/ILCompiler.Compiler/src/Compiler/UtcNameMangler.cs b/src/ILCompiler.Compiler/src/Compiler/UtcNameMangler.cs index 45e32e38c25..5943a5ed617 100644 --- a/src/ILCompiler.Compiler/src/Compiler/UtcNameMangler.cs +++ b/src/ILCompiler.Compiler/src/Compiler/UtcNameMangler.cs @@ -37,17 +37,6 @@ public class UTCNameMangler : NameMangler private string OrdinalPrefix => "_[O]_"; private string deDuplicatePrefix => "_[D]_"; - // The max length of name allowed in terms of UTF8 string. This is the limit from the compiler. - private int _maximumUTF8NameLength = 4000; - - // The max length of prefix+suffix added to the name in terms of UTF8 string. This is usually for generated - // hash code, node-specific prefixes and suffixes, and ordinal prefixes. - private int _nameUTF8MarginLength = 1000; - -#if DEBUG - ConcurrentDictionary _longNames = new ConcurrentDictionary(); -#endif - private ImportExportOrdinals _importOrdinals; private ImportExportOrdinals _exportOrdinals; @@ -241,33 +230,7 @@ private string DisambiguateName(string origName, ISet set) result = string.Concat(origName, deDuplicatePrefix, (iter++).ToStringInvariant()); } return result; - } - - private string TruncateName(string origName) - { - // A UTF8 char can only expand to 3 bytes - if (origName.Length * 3 <= _maximumUTF8NameLength) - { - return origName; - } - - // Compute the exact UTF8 length and compare - if (Encoding.UTF8.GetBytes(origName).Length <= _maximumUTF8NameLength) - { - return origName; - } - - var hash = _sha256.ComputeHash(GetBytesFromString(origName)); - var truncatedName = origName.Substring(0, _maximumUTF8NameLength - _nameUTF8MarginLength); - truncatedName = truncatedName + BitConverter.ToString(hash).Replace("-", ""); - -#if DEBUG - string existingName = _longNames.GetOrAdd(truncatedName, origName); - Debug.Assert(existingName == origName); -#endif - - return truncatedName; - } + } public override string GetMangledTypeName(TypeDesc type) { @@ -328,7 +291,6 @@ private string ComputeMangledTypeName(TypeDesc type) // Ensure that name is unique and update our tables accordingly. name = DisambiguateName(name, deduplicator); deduplicator.Add(name); - name = TruncateName(name); _mangledTypeNames = _mangledTypeNames.Add(t, name); } } @@ -390,8 +352,6 @@ private string ComputeMangledTypeName(TypeDesc type) break; } - mangledName = TruncateName(mangledName); - lock (this) { // Ensure that name is unique and update our tables accordingly. @@ -487,8 +447,6 @@ private Utf8String ComputeMangledNameMethodWithoutInstantiation(MethodDesc metho if (prependTypeName != null) name = prependTypeName + "__" + name; - - name = TruncateName(name); } _mangledMethodNames = _mangledMethodNames.Add(m, name); @@ -535,8 +493,6 @@ private Utf8String ComputeMangledMethodName(MethodDesc method) mangledName += mangledInstantiation; } - mangledName = TruncateName(mangledName); - lock (this) { utf8MangledName = new Utf8String(mangledName); @@ -613,8 +569,6 @@ private Utf8String ComputeMangledFieldName(FieldDesc field) if (prependTypeName != null) name = prependTypeName + "__" + name; - name = TruncateName(name); - _mangledFieldNames = _mangledFieldNames.Add(f, name); } } @@ -629,8 +583,6 @@ private Utf8String ComputeMangledFieldName(FieldDesc field) if (prependTypeName != null) mangledName = prependTypeName + "__" + mangledName; - mangledName = TruncateName(mangledName); - Utf8String utf8MangledName = new Utf8String(mangledName); lock (this) diff --git a/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs index df3b910293c..26756641fb2 100644 --- a/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs +++ b/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs @@ -9,9 +9,6 @@ using Internal.Runtime; -// Disable: Filter expression is a constant. We know. We just can't do an unfiltered catch. -#pragma warning disable 7095 - namespace System.Runtime { public enum RhFailFastReason @@ -183,7 +180,7 @@ internal static void FailFastViaClasslib(RhFailFastReason reason, object unhandl // Invoke the classlib fail fast function. CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, IntPtr.Zero, IntPtr.Zero); } - catch when (true) + catch { // disallow all exceptions leaking out of callbacks } @@ -229,7 +226,7 @@ private static void OnFirstChanceExceptionViaClassLib(object exception) { CalliIntrinsics.CallVoid(pOnFirstChanceFunction, exception); } - catch when (true) + catch { // disallow all exceptions leaking out of callbacks } @@ -261,7 +258,7 @@ internal static unsafe void UnhandledExceptionFailFastViaClasslib( { CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, exInfo._pExContext->IP, (IntPtr)pContext); } - catch when (true) + catch { // disallow all exceptions leaking out of callbacks } @@ -291,7 +288,7 @@ private static void AppendExceptionStackFrameViaClasslib(object exception, IntPt { CalliIntrinsics.CallVoid(pAppendStackFrame, exception, IP, flags); } - catch when (true) + catch { // disallow all exceptions leaking out of callbacks } @@ -318,7 +315,7 @@ internal static Exception GetClasslibException(ExceptionIDs id, IntPtr address) { e = CalliIntrinsics.Call(pGetRuntimeExceptionFunction, id); } - catch when (true) + catch { // disallow all exceptions leaking out of callbacks } @@ -354,7 +351,7 @@ internal static Exception GetClasslibExceptionFromEEType(ExceptionIDs id, IntPtr { e = CalliIntrinsics.Call(pGetRuntimeExceptionFunction, id); } - catch when (true) + catch { // disallow all exceptions leaking out of callbacks } @@ -876,38 +873,28 @@ private static bool FindFirstPassHandler(object exception, uint idxStart, return false; } -#if DEBUG && !INPLACE_RUNTIME private static EEType* s_pLowLevelObjectType; - private static void AssertNotRuntimeObject(EEType* pClauseType) + + private static bool ShouldTypedClauseCatchThisException(object exception, EEType* pClauseType) { - // - // The C# try { } catch { } clause expands into a typed catch of System.Object. - // Since runtime has its own definition of System.Object, try { } catch { } might not do what - // was intended (catch all exceptions). - // - // This assertion is making sure we don't use try { } catch { } within the runtime. - // The runtime codebase should either use try { } catch (Exception) { } for exception types - // from the runtime or a try { } catch when (true) { } to catch all exceptions. - // + if (TypeCast.IsInstanceOfClass(exception, pClauseType) != null) + return true; if (s_pLowLevelObjectType == null) { - // Allocating might fail, but since this is just a debug assert, it's probably fine. + // TODO: Avoid allocating here as that may fail s_pLowLevelObjectType = new System.Object().EEType; } - Debug.Assert(!pClauseType->IsEquivalentTo(s_pLowLevelObjectType)); - } -#endif // DEBUG && !INPLACE_RUNTIME + // This allows the typical try { } catch { }--which expands to a typed catch of System.Object--to work on + // all objects when the clause is in the low level runtime code. This special case is needed because + // objects from foreign type systems are sometimes throw back up at runtime code and this is the only way + // to catch them outside of having a filter with no type check in it, which isn't currently possible to + // write in C#. See https://github.com/dotnet/roslyn/issues/4388 + if (pClauseType->IsEquivalentTo(s_pLowLevelObjectType)) + return true; - - private static bool ShouldTypedClauseCatchThisException(object exception, EEType* pClauseType) - { -#if DEBUG && !INPLACE_RUNTIME - AssertNotRuntimeObject(pClauseType); -#endif - - return TypeCast.IsInstanceOfClass(exception, pClauseType) != null; + return false; } private static void InvokeSecondPass(ref ExInfo exInfo, uint idxStart) diff --git a/src/Runtime.Base/src/System/Runtime/ThunkPool.cs b/src/Runtime.Base/src/System/Runtime/ThunkPool.cs index 76df73e4dc6..404494451eb 100644 --- a/src/Runtime.Base/src/System/Runtime/ThunkPool.cs +++ b/src/Runtime.Base/src/System/Runtime/ThunkPool.cs @@ -135,7 +135,7 @@ public static unsafe ThunksHeap CreateThunksHeap(IntPtr commonStubAddress) if (newHeap._nextAvailableThunkPtr != IntPtr.Zero) return newHeap; } - catch (Exception) { } + catch { } return null; } @@ -156,7 +156,7 @@ private unsafe bool ExpandHeap() { newBlockInfo = new AllocatedBlock(); } - catch (Exception) + catch { return false; }