[runtime] Compare custom modifiers in type equality
commit9dc6c344ac34a470fa0f4fc411e357f7eaf577fd
authorAlexander Kyte <alexmkyte@gmail.com>
Tue, 13 Feb 2018 22:04:24 +0000 (13 17:04 -0500)
committerAleksey Kliger (λgeek) <akliger@gmail.com>
Mon, 9 Apr 2018 20:46:55 +0000 (9 16:46 -0400)
treed89cf28417a3e476b5fb7ffb4d973c628cd0743c
parentc78ae5d6fd302b846f87fe9d9c16b2d9d18b22ac
[runtime] Compare custom modifiers in type equality

Custom modifiers are an odd feature of .net which allow types to
be tagged. These tags are semantically relevant. A method with a
modifier should not override a method without a modifier, for
instance (github bug #6936).

We don't put enough information into the modifier to uniquely find the
Image associated with the token we have in the type. Modifiers from
different referring assemblies will have different tokens to refer to
the same modifier class, making it important to resolve the tokens to
MonoClass pointers at runtime. Pointer equality of these classes is the
way to determine two custom modifiers the same, or unique.

We cannot resolve the image just from the MonoType because it is
possible to put modifiers on primitive, builtin types. These builtin
types lack any filled-out pointers in the data block, meaning we have
zero metadata associated with our floating token.

Other places in the codebase fixed this by passing around MonoImages,
but adding a MonoImage argument to our type comparison function for
this single bug would be a very poor decision with much code churn all
throughout the runtime.

The bug above resolves to two I4 types, one of which has a modifier, one
of which does not.

In order to pass this MonoImage around, we need to put a reference to it
into something reachable from the MonoType. We can't put it in the
custom module type because that is exported. It is part of the public
API.

MonoTypes do not adhere to pointer equality, and custom modules are structs
baked directly into the MonoType. We need therefore to make MonoType
point to a MonoCustomModInternal, a new type. This type embeds the
public type as a struct and carries around the image as another element
in the struct.

All public interfaces still see the same metadata endpoints for parsing the
modules, including the icalls. It is only our type comparison code that
accesses our new field.
mono/dis/get.c
mono/metadata/icall.c
mono/metadata/marshal.c
mono/metadata/metadata-internals.h
mono/metadata/metadata.c
mono/metadata/metadata.h
mono/metadata/sre-encode.c
mono/metadata/sre.c
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c