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:
Diffstat (limited to 'src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs b/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs
index 9b8bd363c..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);
@@ -325,14 +335,14 @@ namespace ILCompiler
}
flags |= TypeFlags.HasFinalizerComputed;
- flags |= TypeFlags.IsByRefLikeComputed;
+ flags |= TypeFlags.AttributeCacheComputed;
return flags;
}
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])