Skip to content
2 changes: 1 addition & 1 deletion mono/metadata/class-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
122 changes: 122 additions & 0 deletions mono/metadata/unity-utils.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "unity-utils.h"
#include <config.h>


Expand Down Expand Up @@ -31,6 +32,7 @@
#include <mono/metadata/threadpool.h>
#include <mono/metadata/tokentype.h>
#include <mono/utils/mono-string.h>
#include "mono/metadata/custom-attrs-internals.h"

#if HAVE_BOEHM_GC
#include <mono/utils/gc_wrapper.h>
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
35 changes: 27 additions & 8 deletions mono/metadata/unity-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -144,15 +144,16 @@ 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
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
Expand All @@ -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);
Expand Down Expand Up @@ -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