Ambiguity in Generic Parameters in the Cecil object model

4 views
Skip to first unread message

Rune Glerup

unread,
May 8, 2008, 6:19:30 PM5/8/08
to mono-cecil
I am having some trouble with an apparent difference between
assemblies compiled with csc and gmcs.

Consider the following C# program:

public interface J<T> { }
public interface K<U> : J<U> { }
public class C<V> : K<V> { }

When disassembled with monodis:

.class public auto ansi beforefieldinit C`1<V>
extends [mscorlib]System.Object
implements class K`1<!0>, class J`1<!0> { ... }

In my understanding of CIL and the object model of Cecil, the type
arguments for the generic type instances K`1<!0> and J`1<!0> should
point to the GenericParameter object representing V (owned by C).

This is the case when the program is compiled with gmcs.

But when the program is compiled with csc the type argument of the the
type argument for the generic type instance J`1<!0> points to the
object representing U owned by K`1<U>.

I can peverify both versions. How should I interpret this? Are both
encodings legal?

Any useful insights will be much welcomed! :)

Rune Glerup

unread,
May 12, 2008, 7:05:19 AM5/12/08
to mono-cecil
I came up with an even weirder example! (Again only weird when
compiled with the Visual C# compiler.)

public interface J<T> { }
public interface K<U> : J<U> { }
public abstract class B<W> : K<W> { }
public class C<V> : K<V> { }

Here the GenericParamter object representing "!0" in the
GenericInstanceType K`1<!0> is W (owned by B`1<W>) and the object
representing "!0" in J`1<!0> is U (owned by K`1<U>).

Why is the type C allowed to implement a generic type instance with a
type argument that is a type parameter owned by a completely unrelated
type?

Jb Evain

unread,
May 12, 2008, 7:12:27 AM5/12/08
to mono-...@googlegroups.com
Hey,

On 5/12/08, Rune Glerup <rune....@gmail.com> wrote:
>
> I came up with an even weirder example! (Again only weird when
> compiled with the Visual C# compiler.)

Thanks for the example, I'll investigate.

--
Jb Evain <j...@nurv.fr>

Rune Glerup

unread,
May 20, 2008, 6:13:12 AM5/20/08
to mono-cecil
On May 12, 1:12 pm, "Jb Evain" <j...@nurv.fr> wrote:

> Thanks for the example, I'll investigate.

I think the problem may stem from how TypeSpecification objects are
cached in the class ReflectionReader.

Consider the following code:

public TypeReference GetTypeSpecAt (uint rid, GenericContext context)
{
if (rid > m_typeSpecs.Length)
return null;

int index = (int) rid - 1;
TypeReference tspec = m_typeSpecs [index];
if (tspec != null)
return tspec;
...
}

If a TypeSpecification object of the appropriate index has been cached
in the m_typeSpecs array, it is returned unchanged.

As I understand the metadata model, the TypeSpecification object
returned by this method depends on the GenericContext, but this is
circumvented using this caching scheme and in effect a
TypeSpecification potentially based on a different GenericContext
object is returned instead.

So maybe it does not make sense to cache the TypeSpecification objects
by index alone in the way it is done here? Maybe it should either not
be cached or cached by context and index?
Reply all
Reply to author
Forward
0 new messages