diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2018-06-22 10:23:16 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-22 10:23:16 +0300 |
commit | f61d47a928b3049a2adbec9bbbf13754ff576f5f (patch) | |
tree | ad26066ba68e226008140cd1ec5e2f78473639ec /src/ILCompiler.Compiler | |
parent | 6fa2c229713ed6921b91f7308dee14d961d8c070 (diff) | |
parent | 611f1a04e3d27bdbacd8183668610790a95ee6a3 (diff) |
Merge pull request #5992 from dotnet/nmirror
Merge nmirror to master
Diffstat (limited to 'src/ILCompiler.Compiler')
4 files changed, 36 insertions, 10 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs b/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs index 44e7ec038..71b9720fc 100644 --- a/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs +++ b/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs @@ -290,7 +290,17 @@ namespace ILCompiler Module = owningModule; ValueTypeRepresented = valuetype; - BoxedValue = new BoxedValueField(this); + + // Unboxing thunks for byref-like types don't make sense. Byref-like types cannot be boxed. + // We still allow these to exist in the system, because it's easier than trying to prevent + // their creation. We create them as if they existed (in lieu of e.g. pointing all of them + // to the same __unreachable method body) so that the various places that store pointers to + // them because they want to be able to extract the target instance method can use the same + // mechanism they use for everything else at runtime. + // The main difference is that the "Boxed_ValueType" version has no fields. Reference types + // cannot have byref-like fields. + if (!valuetype.IsByRefLike) + BoxedValue = new BoxedValueField(this); } public override ClassLayoutMetadata GetClassLayout() => default(ClassLayoutMetadata); @@ -332,7 +342,7 @@ namespace ILCompiler public override FieldDesc GetField(string name) { - if (name == BoxedValueFieldName) + if (name == BoxedValueFieldName && BoxedValue != null) return BoxedValue; return null; @@ -340,7 +350,10 @@ namespace ILCompiler public override IEnumerable<FieldDesc> GetFields() { - yield return BoxedValue; + if (BoxedValue != null) + return new FieldDesc[] { BoxedValue }; + + return Array.Empty<FieldDesc>(); } /// <summary> @@ -439,6 +452,15 @@ namespace ILCompiler public override MethodIL EmitIL() { + if (_owningType.BoxedValue == null) + { + // If this is the fake unboxing thunk for ByRef-like types, just make a method that throws. + return new ILStubMethodIL(this, + new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ }, + Array.Empty<LocalVariableDefinition>(), + Array.Empty<object>()); + } + // Generate the unboxing stub. This loosely corresponds to following C#: // return BoxedValue.InstanceMethod(this.m_pEEType, [rest of parameters]) @@ -507,6 +529,15 @@ namespace ILCompiler public override MethodIL EmitIL() { + if (_owningType.BoxedValue == null) + { + // If this is the fake unboxing thunk for ByRef-like types, just make a method that throws. + return new ILStubMethodIL(this, + new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ }, + Array.Empty<LocalVariableDefinition>(), + Array.Empty<object>()); + } + // Generate the unboxing stub. This loosely corresponds to following C#: // return BoxedValue.InstanceMethod([rest of parameters]) diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs index 07efe41dd..70e39e6c1 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs @@ -27,7 +27,6 @@ namespace ILCompiler.DependencyAnalysis Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any)); Debug.Assert(type == type.ConvertToCanonForm(CanonicalFormKind.Specific)); Debug.Assert(!type.IsMdArray); - Debug.Assert(!type.IsByRefLike); } public override bool StaticDependenciesAreComputed => true; diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 6f9d6016a..23a9a47d2 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -204,10 +204,6 @@ namespace ILCompiler.DependencyAnalysis if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) return false; - // Byref-like types have interior pointers and cannot be heap allocated. - if (type.IsByRefLike) - return false; - // The global "<Module>" type can never be allocated. if (((MetadataType)type).IsModuleType) return false; diff --git a/src/ILCompiler.Compiler/src/Compiler/ILStreamReader.cs b/src/ILCompiler.Compiler/src/Compiler/ILStreamReader.cs index 8facc05f7..badf0151a 100644 --- a/src/ILCompiler.Compiler/src/Compiler/ILStreamReader.cs +++ b/src/ILCompiler.Compiler/src/Compiler/ILStreamReader.cs @@ -179,9 +179,9 @@ namespace Internal.Compiler try { tokenResolved = TryReadLdtoken(out token); - entity = tokenResolved ?(TypeSystemEntity)_methodIL.GetObject(token) : null; + entity = tokenResolved ? (TypeSystemEntity)_methodIL.GetObject(token) : null; } - catch (TypeSystemException.TypeLoadException) + catch (TypeSystemException) { tokenResolved = false; entity = null; |