diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2017-05-20 05:37:19 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-20 05:37:19 +0300 |
commit | 422c171ff9a8e38c3e349d17c2e1344042258ff1 (patch) | |
tree | 3ae0f9fbe8477d3fcc5e369e1b58183b09784863 /src | |
parent | c723f00d3d95f3a3f6e08a30ea371758e0abb1c7 (diff) |
Emit interface generic dictionaries (#3658)
Generic interface types have a generic dictionary slot like any other
type, except sometimes the slot is null.
We can now call static methods on generic interfaces with a usable
generic context.
Got reminded of this while reading about the planned C# language support
for static methods on interfaces. I didn't want to push on it when #3100
added the logic, but it turns out this is really easy.
Diffstat (limited to 'src')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs index f5a762cb5..ed80e29bc 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs @@ -435,9 +435,14 @@ namespace ILCompiler.DependencyAnalysis // The generic dictionary pointer occupies the first slot of each type vtable slice if (declType.HasGenericDictionarySlot()) { + // All generic interface types have a dictionary slot, but only some of them have an actual dictionary. + bool isInterfaceWithAnEmptySlot = declType.IsInterface && + declType.ConvertToCanonForm(CanonicalFormKind.Specific) == declType; + // Note: Canonical type instantiations always have a generic dictionary vtable slot, but it's empty - // TODO: emit the correction dictionary slot for interfaces (needed when we start supporting static methods on interfaces) - if (declType.IsInterface || declType.IsCanonicalSubtype(CanonicalFormKind.Any) || factory.LazyGenericsPolicy.UsesLazyGenerics(declType)) + if (declType.IsCanonicalSubtype(CanonicalFormKind.Any) + || factory.LazyGenericsPolicy.UsesLazyGenerics(declType) + || isInterfaceWithAnEmptySlot) objData.EmitZeroPointer(); else objData.EmitPointerReloc(factory.TypeGenericDictionary(declType)); |