Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Strehovsky <michals@microsoft.com>2018-06-22 01:21:18 +0300
committerMichal Strehovsky <michals@microsoft.com>2018-06-22 01:21:18 +0300
commit2bcf67a5f1d0a8f1b97bfa0d5e2e084a9678a0e1 (patch)
treec317cfa1a7edad1551063860f9dc083fa2618901 /src/ILCompiler.Compiler
parent5821d7e3cd349af97829cc5d2cc3b6c682a420c1 (diff)
Allow constructed byref-like types
We were not allowing these because we couldn't properly fill out the vtable (can't really make unboxing thunks to put in the vtable). We actually need the vtable, but only because the generic dictionary lives there and reflection might touch it. [tfs-changeset: 1705047]
Diffstat (limited to 'src/ILCompiler.Compiler')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs37
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs1
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs4
3 files changed, 34 insertions, 8 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;