MONO_WRAPPER_PROXY_ISINST,
MONO_WRAPPER_STELEMREF,
MONO_WRAPPER_UNBOX,
+ MONO_WRAPPER_LDFLDA,
MONO_WRAPPER_UNKNOWN
} MonoWrapperType;
guint32 token;
MonoClass *klass;
MonoMethodSignature *signature;
+ MonoGenericContainer *generic_container;
/* name is useful mostly for debugging */
const char *name;
/* this is used by the inlining algorithm */
unsigned int string_ctor:1;
unsigned int save_lmf:1;
unsigned int dynamic:1; /* created & destroyed during runtime */
- unsigned int is_inflated:1;
+ unsigned int is_inflated:1; /* whether we're a MonoMethodInflated */
signed int slot : 21;
};
struct _MonoMethodNormal {
MonoMethod method;
- MonoGenericContainer *generic_container;
MonoMethodHeader *header;
};
void *method_data;
};
-struct _MonoMethodInflated {
- MonoMethodNormal nmethod;
- MonoGenericContext *context;
- MonoMethod *declaring;
- MonoMethodInflated *inflated;
-};
-
struct _MonoMethodPInvoke {
MonoMethod method;
gpointer addr;
guint16 implmap_idx; /* index into IMPLMAP */
};
+/*
+ * Inflated generic method.
+ */
+struct _MonoMethodInflated {
+ union {
+ MonoMethod method;
+ MonoMethodNormal normal;
+ MonoMethodPInvoke pinvoke;
+ } method;
+ MonoGenericContext *context; /* The current context. */
+ MonoMethod *declaring; /* the generic method definition. */
+ /* This is a big performance optimization:
+ *
+ * mono_class_inflate_generic_method() just creates a copy of the method
+ * and computes its new context, but it doesn't actually inflate the
+ * method's signature and header. Very often, we don't actually need them
+ * (for instance because the method is stored in a class'es vtable).
+ *
+ * If the `inflated' field in non-NULL, mono_get_inflated_method() already
+ * inflated the signature and header and stored it there.
+ */
+ MonoMethodInflated *inflated;
+};
+
typedef struct {
MonoType *generic_type;
gpointer reflection_info;
};
/* a field is ignored if it's named "_Deleted" and it has the specialname and rtspecialname flags set */
-#define mono_field_is_deleted(field) ((field)->name[0] == '_' && ((field)->type->attrs & 0x600) && (strcmp ((field)->name, "_Deleted") == 0))
+#define mono_field_is_deleted(field) (((field)->type->attrs & (FIELD_ATTRIBUTE_SPECIAL_NAME | FIELD_ATTRIBUTE_RT_SPECIAL_NAME)) \
+ && (strcmp ((field)->name, "_Deleted") == 0))
typedef struct {
MonoClassField *field;
/* next byte */
guint has_references : 1; /* it has GC-tracked references in the instance */
guint has_static_refs : 1; /* it has static fields that are GC-tracked */
+ guint no_special_static_fields : 1; /* has no thread/context static fields */
- guint32 declsec_flags; /* declarative security attributes flags */
- guint32 exception_type; /* MONO_EXCEPTION_* */
+ guint8 exception_type; /* MONO_EXCEPTION_* */
void* exception_data; /* Additional information about the exception */
+ guint32 declsec_flags; /* declarative security attributes flags */
MonoClass *parent;
MonoClass *nested_in;
*/
guint32 flags;
struct {
- guint32 first, last;
- int count;
+ guint32 first, count;
} field, method, property, event;
/* loaded on demand */
/*
* Generic instantiation data type encoding.
*/
+
+/*
+ * A particular generic instantiation:
+ *
+ * All instantiations are cached and we don't distinguish between class and method
+ * instantiations here.
+ */
struct _MonoGenericInst {
- guint id;
- guint type_argc : 22;
- guint is_open : 1;
- guint is_reference : 1;
+ guint id; /* unique ID for debugging */
+ guint type_argc : 22; /* number of type arguments */
+ guint is_open : 1; /* if this is an open type */
+ guint is_reference : 1; /* if this is a reference type */
MonoType **type_argv;
};
+/*
+ * A particular instantiation of a generic type.
+ */
struct _MonoGenericClass {
- MonoGenericInst *inst;
- MonoClass *container_class;
- MonoGenericContext *context;
+ MonoGenericInst *inst; /* the instantiation */
+ MonoClass *container_class; /* the generic type definition */
+ MonoGenericContext *context; /* current context */
+ guint is_dynamic : 1; /* We're a MonoDynamicGenericClass */
+ guint is_inflated : 1; /* We're a MonoInflatedGenericClass */
+};
+
+/*
+ * Performance optimization:
+ * We don't create the `MonoClass' for a `MonoGenericClass' until we really
+ * need it.
+ */
+struct _MonoInflatedGenericClass {
+ MonoGenericClass generic_class;
+ guint is_initialized : 1;
MonoClass *klass;
- MonoType *parent;
- guint count_ifaces : 29;
- guint is_dynamic : 1;
- MonoType **ifaces;
};
+/*
+ * This is used when instantiating a generic type definition which is
+ * a TypeBuilder.
+ */
struct _MonoDynamicGenericClass {
- MonoGenericClass generic_class;
+ MonoInflatedGenericClass generic_class;
+ MonoType *parent;
+ int count_ifaces;
+ MonoType **ifaces;
int count_methods;
MonoMethod **methods;
int count_ctors;
guint initialized;
};
+/*
+ * A particular instantiation of a generic method.
+ */
struct _MonoGenericMethod {
- MonoGenericInst *inst;
- MonoGenericClass *generic_class;
- MonoGenericContainer *container;
+ MonoGenericInst *inst; /* the instantiation */
+ MonoGenericClass *generic_class; /* if we're in a generic type */
+ MonoGenericContainer *container; /* type parameters */
gpointer reflection_info;
};
+/*
+ * The generic context.
+ */
struct _MonoGenericContext {
+ /*
+ * The current container:
+ *
+ * If we're in a generic method, the generic method definition's container.
+ * Otherwise the generic type's container.
+ */
MonoGenericContainer *container;
+ /* The current generic class */
MonoGenericClass *gclass;
+ /* The current generic method */
MonoGenericMethod *gmethod;
};
+/*
+ * The generic container.
+ *
+ * Stores the type parameters of a generic type definition or a generic method definition.
+ */
struct _MonoGenericContainer {
MonoGenericContext context;
+ /* If we're a generic method definition, the containing class'es context. */
MonoGenericContainer *parent;
+ /* If we're a generic method definition, caches all their instantiations. */
GHashTable *method_hash;
+ /* If we're a generic type definition, its `MonoClass'. */
MonoClass *klass;
int type_argc : 6;
+ /* If true, we're a generic method, otherwise a generic type definition. */
int is_method : 1;
- int is_signature : 1;
+ /* Our type parameters. */
MonoGenericParam *type_params;
+ /* Cache for MonoTypes */
+ MonoType **types;
};
+/*
+ * A type parameter.
+ */
struct _MonoGenericParam {
- MonoGenericContainer *owner;
- MonoClass *pklass;
- MonoMethod *method;
+ MonoGenericContainer *owner; /* Type or method this parameter was defined in. */
+ MonoClass *pklass; /* The corresponding `MonoClass'. */
+ MonoMethod *method; /* If we're a method type parameter, the method. */
const char *name;
guint16 flags;
guint16 num;
guint has_finalize : 1;
guint ghcimpl : 1;
guint has_cctor : 1;
+ guint has_nested_classes : 1;
+ guint blittable : 1;
+ guint has_references : 1;
+ guint has_static_refs : 1;
+ guint no_special_static_fields : 1;
guint32 cctor_token;
MonoImage *finalize_image;
guint32 finalize_token;
+ guint32 instance_size;
+ guint32 class_size;
+ guint32 packing_size;
+ guint32 min_align;
} MonoCachedClassInfo;
typedef struct {
MonoMethodSignature *sig;
} MonoJitICallInfo;
+/*
+ * Information about a type load error encountered by the loader.
+ */
+typedef enum {
+ MONO_LOADER_ERROR_TYPE,
+ MONO_LOADER_ERROR_METHOD,
+ MONO_LOADER_ERROR_FIELD
+} MonoLoaderErrorKind;
+
+typedef struct {
+ MonoLoaderErrorKind kind;
+ char *class_name, *assembly_name; /* If kind == TYPE */
+ MonoClass *klass; /* If kind != TYPE */
+ const char *member_name; /* If kind != TYPE */
+} MonoLoaderError;
+
#define mono_class_has_parent(klass,parent) (((klass)->idepth >= (parent)->idepth) && ((klass)->supertypes [(parent)->idepth - 1] == (parent)))
typedef struct {
typedef gpointer (*MonoTrampoline) (MonoMethod *method);
typedef gpointer (*MonoRemotingTrampoline) (MonoMethod *method, MonoRemotingTarget target);
+typedef gpointer (*MonoDelegateTrampoline) (MonoMethod *method, gpointer addr);
typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, MonoClass **handle_class);
gboolean
mono_class_is_open_constructed_type (MonoType *t);
-MonoMethod**
-mono_class_get_overrides_full (MonoImage *image, guint32 type_token, gint32 *num_overrides,
+gboolean
+mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod ***overrides, gint32 *num_overrides,
MonoGenericContext *generic_context);
MonoMethod*
gboolean
mono_class_needs_cctor_run (MonoClass *klass, MonoMethod *caller);
+gboolean
+mono_class_has_special_static_fields (MonoClass *klass);
+
void
mono_install_trampoline (MonoTrampoline func);
void
mono_install_remoting_trampoline (MonoRemotingTrampoline func);
+void
+mono_install_delegate_trampoline (MonoDelegateTrampoline func);
+
gpointer
mono_lookup_dynamic_token (MonoImage *image, guint32 token);
void
mono_install_get_cached_class_info (MonoGetCachedClassInfo func);
-void
-mono_class_create_generic (MonoGenericClass *gclass);
+MonoInflatedGenericClass*
+mono_get_inflated_generic_class (MonoGenericClass *gclass);
typedef struct {
MonoImage *corlib;
MonoClass *iremotingtypeinfo_class;
MonoClass *runtimesecurityframe_class;
MonoClass *executioncontext_class;
+ MonoClass *generic_array_class;
+ MonoClass *generic_nullable_class;
} MonoDefaults;
extern MonoDefaults mono_defaults;
void
mono_loader_unlock (void);
+void
+mono_loader_set_error_type_load (char *class_name, char *assembly_name);
+
+void
+mono_loader_set_error_method_load (MonoClass *klass, const char *member_name);
+
+void
+mono_loader_set_error_field_load (MonoClass *klass, const char *member_name);
+
+MonoLoaderError*
+mono_loader_get_last_error (void);
+
+void
+mono_loader_clear_error (void);
+
void
mono_icall_init (void);
gboolean
mono_metadata_has_generic_params (MonoImage *image, guint32 token);
-MonoGenericContainer *mono_metadata_load_generic_params (MonoImage *image, guint32 token,
- MonoGenericContainer *parent_container);
+MonoGenericContainer *
+mono_metadata_load_generic_params (MonoImage *image, guint32 token,
+ MonoGenericContainer *parent_container);
+
+void
+mono_metadata_load_generic_param_constraints (MonoImage *image, guint32 token,
+ MonoGenericContainer *container);
MonoMethodSignature*
mono_create_icall_signature (const char *sigstr);
mono_class_inflate_generic_signature (MonoImage *image, MonoMethodSignature *sig, MonoGenericContext *context);
MonoMethodSignature *
-mono_method_signature_full (MonoMethod *image, MonoGenericContext *context);
+mono_method_signature_full (MonoMethod *image, MonoGenericContainer *container);
MonoGenericClass *
mono_get_shared_generic_class (MonoGenericContainer *container, gboolean is_dynamic);
char*
mono_type_get_name_full (MonoType *type, MonoTypeNameFormat format);
+char*
+mono_type_get_full_name (MonoClass *class);
+
+MonoArrayType *mono_dup_array_type (MonoArrayType *a);
+MonoMethodSignature *mono_metadata_signature_deep_dup (MonoMethodSignature *sig);
+
+gboolean mono_class_is_nullable (MonoClass *klass);
+MonoClass *mono_class_get_nullable_param (MonoClass *klass);
+
#endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */