diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index 8f9d3cd93dc1..05941381dbdc 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -1569,7 +1569,7 @@ mono_class_enum_basetype_internal (MonoClass *klass); gboolean mono_method_is_constructor (MonoMethod *method); -gboolean +MONO_API gboolean mono_class_has_default_constructor (MonoClass *klass, gboolean public_only); gboolean diff --git a/mono/metadata/unity-utils.c b/mono/metadata/unity-utils.c index 7a0ea2d221ff..8f0067f3025e 100644 --- a/mono/metadata/unity-utils.c +++ b/mono/metadata/unity-utils.c @@ -1,3 +1,4 @@ +#include "unity-utils.h" #include @@ -31,6 +32,7 @@ #include #include #include +#include "mono/metadata/custom-attrs-internals.h" #if HAVE_BOEHM_GC #include @@ -823,6 +825,11 @@ MonoGenericContext mono_unity_generic_class_get_context(MonoGenericClass *klass) return klass->context; } +void mono_unity_generic_class_get_context_by_ptr(MonoGenericClass *klass, MonoGenericContext *context) +{ + *context = klass->context; +} + MonoClass* mono_unity_generic_class_get_container_class(MonoGenericClass *klass) { return klass->container_class; @@ -2049,3 +2056,118 @@ ves_icall_Unity_Android_Network_Interface_Up_State (MonoString *ifName, MonoBool } #endif +MonoAttrArgsInfo* mono_unity_get_attr_args_info(MonoCustomAttrInfo *cainfo, int index) +{ + g_assert(index < cainfo->num_attrs); + + MonoCustomAttrEntry *centry = &cainfo->attrs [index]; + if (centry->ctor == NULL) + return NULL; + + //MonoClass *klass = centry->ctor->klass; + //if (strcmp (m_class_get_name (klass), "CategoryAttribute") || mono_method_signature_internal (centry->ctor)->param_count != 1) + // continue; + + MonoAttrArgsInfo *attr_args_info = g_malloc(sizeof(MonoAttrArgsInfo)); + MonoMethodSignature *sig = mono_method_signature_internal(centry->ctor); + attr_args_info->num_type_args = sig->param_count; + + ERROR_DECL (error); + mono_reflection_create_custom_attr_data_args_noalloc ( + cainfo->image, centry->ctor, centry->data, centry->data_size, + &attr_args_info->typed_args, &attr_args_info->named_args, &attr_args_info->num_named_args, &attr_args_info->arginfo, error); + if (!is_ok (error)) + { + mono_error_cleanup (error); + g_free(attr_args_info); + return NULL; + } + + mono_error_cleanup (error); + + return attr_args_info; + + //g_free (typed_args); + //g_free (named_args); + //g_free (arginfo); +} + +void mono_unity_get_attr_args_info_free(MonoAttrArgsInfo *ainfo) +{ + g_free(ainfo->typed_args); + g_free(ainfo->named_args); + g_free(ainfo->arginfo); + g_free(ainfo); +} + +gint32 mono_unity_get_attr_args_info_type_arg_count(MonoAttrArgsInfo *ainfo) +{ + return ainfo->num_type_args; +} + +MonoClass* mono_unity_get_attr_type_arg_as_class(MonoAttrArgsInfo *ainfo, int index) +{ + g_assert(index < ainfo->num_type_args); + return mono_class_from_mono_type((MonoType*)ainfo->typed_args[index]); +} + +int mono_unity_get_attr_type_arg_as_int(MonoAttrArgsInfo *ainfo, int index) +{ + g_assert(index < ainfo->num_type_args); + return *(int*)(ainfo->typed_args[index]); +} + +uint64_t mono_unity_get_attr_type_arg_as_uint64(MonoAttrArgsInfo *ainfo, int index) +{ + g_assert(index < ainfo->num_type_args); + return *(uint64_t*)(ainfo->typed_args[index]); +} + +void* mono_unity_get_attr_type_arg(MonoAttrArgsInfo *ainfo, int index) +{ + g_assert(index < ainfo->num_type_args); + return ainfo->typed_args[index]; +} + +const char* mono_unity_class_get_assembly_name_cstring(MonoClass *klass) +{ + MonoAssembly *ta = m_class_get_image (klass)->assembly; + return (const char*)mono_stringify_assembly_name (&ta->aname); +} + +gboolean mono_unity_type_is_blittable_primitive(MonoType *type) +{ + return (type->type >= MONO_TYPE_BOOLEAN && type->type <= MONO_TYPE_R8) || + type-> type == MONO_TYPE_I || type->type == MONO_TYPE_U || type->type == MONO_TYPE_PTR; +} + +gboolean mono_unity_type_is_unmanaged(MonoType *type) +{ + if (mono_unity_type_is_blittable_primitive(type)) + return TRUE; + + MonoClass* klass = mono_class_from_mono_type(type); + + // if it's not a valuetype, we're done + if (!mono_class_is_valuetype(klass)) + return FALSE; + + // if it's a blittable valuetype, we're done + if (mono_class_is_blittable(klass)) + return TRUE; + + // It's a non-blittable valuetype. We have to look at its fields, + // because we want to allow bools, chars, and other unmanaged fields + // that are not "CLR Blittable" + gpointer iter = NULL; + MonoClassField *field; + while ((field = mono_class_get_fields(klass, &iter))) + { + if ((mono_field_get_flags(field) & FIELD_ATTRIBUTE_STATIC) != 0) + continue; + if (!mono_unity_type_is_unmanaged(mono_field_get_type(field))) + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/mono/metadata/unity-utils.h b/mono/metadata/unity-utils.h index 7cf694aeafa2..121232333b80 100644 --- a/mono/metadata/unity-utils.h +++ b/mono/metadata/unity-utils.h @@ -92,18 +92,18 @@ gboolean mono_unity_object_check_box_cast(MonoObject *obj, MonoClass *klass); //class const char* mono_unity_class_get_image_name(MonoClass* klass); -MonoClass* mono_unity_class_get_generic_definition(MonoClass* klass); +MONO_API MonoClass* mono_unity_class_get_generic_definition(MonoClass* klass); MonoClass* mono_unity_class_inflate_generic_class(MonoClass *gklass, MonoGenericContext *context); gboolean mono_unity_class_has_parent_unsafe(MonoClass *klass, MonoClass *parent); MonoAssembly* mono_unity_class_get_assembly(MonoClass *klass); -gboolean mono_unity_class_is_array(MonoClass *klass); +MONO_API gboolean mono_unity_class_is_array(MonoClass *klass); MonoClass* mono_unity_class_get_element_class(MonoClass *klass); gboolean mono_unity_class_is_delegate(MonoClass *klass); int mono_unity_class_get_instance_size(MonoClass *klass); MonoClass* mono_unity_class_get_castclass(MonoClass *klass); guint32 mono_unity_class_get_native_size(MonoClass* klass); MonoBoolean mono_unity_class_is_string(MonoClass* klass); -MonoBoolean mono_unity_class_is_class_type(MonoClass* klass); +MONO_API MonoBoolean mono_unity_class_is_class_type(MonoClass* klass); MONO_API gboolean mono_unity_class_is_inited(MonoClass* klass); MONO_API gboolean mono_class_is_generic(MonoClass *klass); MONO_API gboolean mono_class_is_blittable(MonoClass *klass); @@ -144,8 +144,8 @@ MonoClass* mono_unity_array_get_class(MonoArray *arr); mono_array_size_t mono_unity_array_get_max_length(MonoArray *arr); //type -gboolean mono_unity_type_is_generic_instance(MonoType *type); -MonoGenericClass* mono_unity_type_get_generic_class(MonoType *type); +MONO_API gboolean mono_unity_type_is_generic_instance(MonoType *type); +MONO_API MonoGenericClass* mono_unity_type_get_generic_class(MonoType *type); gboolean mono_unity_type_is_enum_type(MonoType *type); gboolean mono_unity_type_is_boolean(MonoType *type); MonoClass* mono_unity_type_get_element_class(MonoType *type); //only safe to call when the type has a defined klass data element @@ -153,6 +153,7 @@ guint64 mono_unity_type_get_hash(MonoType *type, gboolean inflate); //generic class MonoGenericContext mono_unity_generic_class_get_context(MonoGenericClass *klass); +MONO_API void mono_unity_generic_class_get_context_by_ptr(MonoGenericClass *klass, MonoGenericContext *context); MonoClass* mono_unity_generic_class_get_container_class(MonoGenericClass *klass); //method signature @@ -161,8 +162,8 @@ int mono_unity_signature_num_parameters(MonoMethodSignature *sig); gboolean mono_unity_signature_param_is_byref(MonoMethodSignature *sig, int index); //generic inst -guint mono_unity_generic_inst_get_type_argc(MonoGenericInst *inst); -MonoType* mono_unity_generic_inst_get_type_argument(MonoGenericInst *inst, int index); +MONO_API guint mono_unity_generic_inst_get_type_argc(MonoGenericInst *inst); +MONO_API MonoType* mono_unity_generic_inst_get_type_argument(MonoGenericInst *inst, int index); //exception MonoString* mono_unity_exception_get_message(MonoException *exc); @@ -276,4 +277,22 @@ mono_unity_set_android_network_up_state_func(android_network_up_state func); MonoBoolean ves_icall_Unity_Android_Network_Interface_Up_State (MonoString *ifName, MonoBoolean* is_up); -#endif +typedef struct { + gpointer *typed_args; + gpointer *named_args; + CattrNamedArg *arginfo; + int num_type_args; + int num_named_args; +} MonoAttrArgsInfo; + +MONO_API MonoAttrArgsInfo* mono_unity_get_attr_args_info(MonoCustomAttrInfo *cainfo, int index); +MONO_API void mono_unity_get_attr_args_info_free(MonoAttrArgsInfo *ainfo); +MONO_API gint32 mono_unity_get_attr_args_info_type_arg_count(MonoAttrArgsInfo *ainfo); +MONO_API MonoClass* mono_unity_get_attr_type_arg_as_class(MonoAttrArgsInfo *ainfo, int index); +MONO_API int mono_unity_get_attr_type_arg_as_int(MonoAttrArgsInfo *ainfo, int index); +MONO_API void* mono_unity_get_attr_type_arg(MonoAttrArgsInfo *ainfo, int index); +MONO_API uint64_t mono_unity_get_attr_type_arg_as_uint64(MonoAttrArgsInfo *ainfo, int index); +MONO_API const char* mono_unity_class_get_assembly_name_cstring(MonoClass *klass); +MONO_API gboolean mono_unity_type_is_unmanaged(MonoType *type); + +#endif \ No newline at end of file