[runtime] Use coop handles in some String-returning icalls
authorAleksey Kliger <aleksey@xamarin.com>
Thu, 11 Aug 2016 20:54:53 +0000 (16:54 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Mon, 29 Aug 2016 16:12:57 +0000 (12:12 -0400)
Also begin adding handle definitions for some System.Reflection classes
when needed.

mcs/class/corlib/System/Environment.cs
mono/metadata/handle.c
mono/metadata/handle.h
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/object-internals.h
mono/metadata/reflection-internals.h
mono/metadata/reflection.c

index 88dff3e3527d2f8e2763e19db2ceb0f85f61d7c0..87096678d30b76a4e4a9632e3446e7e1b42ca0ac 100644 (file)
@@ -472,7 +472,15 @@ namespace System {
                public extern static string[] GetCommandLineArgs ();
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               internal extern static string internalGetEnvironmentVariable (string variable);
+               internal extern static string internalGetEnvironmentVariable_native (IntPtr variable);
+
+               internal static string internalGetEnvironmentVariable (string variable) {
+                       if (variable == null)
+                               return null;
+                       using (var h = Mono.RuntimeMarshal.MarshalString (variable)) {
+                               return internalGetEnvironmentVariable_native (h.Value);
+                       }
+               }
 
                /// <summary>
                /// Return a string containing the value of the environment
index 56b9b9353cd706fc6bab6b125dc0112f9b6a4f92..4be4c632d10e53115c39384faec8f8aa2d0ab2e6 100644 (file)
@@ -157,9 +157,9 @@ mono_stack_mark_pop_value (MonoThreadInfo *info, HandleStackMark *stackmark, Mon
 /* Temporary place for some of the handle enabled wrapper functions*/
 
 MonoStringHandle
-mono_string_new_handle (MonoDomain *domain, const char *data)
+mono_string_new_handle (MonoDomain *domain, const char *data, MonoError *error)
 {
-       return MONO_HANDLE_NEW (MonoString, mono_string_new (domain, data));
+       return MONO_HANDLE_NEW (MonoString, mono_string_new_checked (domain, data, error));
 }
 
 MonoArrayHandle
index f5e8d29ba3088aa08a9acf3f2e4686ab5e9965db..76495a807d56109ecdb674f9158324052ee91916 100644 (file)
@@ -252,6 +252,8 @@ This is why we evaluate index and value before any call to MONO_HANDLE_RAW or ot
        } while (0)
 
 
+#define MONO_HANDLE_DOMAIN(HANDLE) (mono_object_domain (MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject, HANDLE))))
+
 /* Baked typed handles we all want */
 TYPED_HANDLE_DECL (MonoString);
 TYPED_HANDLE_DECL (MonoArray);
@@ -267,7 +269,7 @@ extern const MonoObjectHandle mono_null_value_handle;
 
 
 //FIXME this should go somewhere else
-MonoStringHandle mono_string_new_handle (MonoDomain *domain, const char *data);
+MonoStringHandle mono_string_new_handle (MonoDomain *domain, const char *data, MonoError *error);
 MonoArrayHandle mono_array_new_handle (MonoDomain *domain, MonoClass *eclass, uintptr_t n, MonoError *error);
 
 G_END_DECLS
index 863af471cc5be1ba1c74bed44cc4a96a496c259f..09e66f32fd41de813918f432da66ca7b151b37ad 100644 (file)
@@ -171,7 +171,7 @@ ICALL_TYPE (COMPO_W, "System.ComponentModel.Win32Exception", COMPO_W_1)
 ICALL (COMPO_W_1, "W32ErrorMessage", ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage)
 
 ICALL_TYPE(DEFAULTC, "System.Configuration.DefaultConfig", DEFAULTC_1)
-ICALL(DEFAULTC_1, "get_bundled_machine_config", get_bundled_machine_config)
+HANDLES(ICALL(DEFAULTC_1, "get_bundled_machine_config", get_bundled_machine_config))
 ICALL(DEFAULTC_2, "get_machine_config_path", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path)
 
 /* Note that the below icall shares the same function as DefaultConfig uses */
@@ -281,9 +281,9 @@ ICALL(ENV_14, "get_ProcessorCount", mono_cpu_count)
 ICALL(ENV_15, "get_TickCount", ves_icall_System_Environment_get_TickCount)
 ICALL(ENV_16, "get_UserName", ves_icall_System_Environment_get_UserName)
 ICALL(ENV_16m, "internalBroadcastSettingChange", ves_icall_System_Environment_BroadcastSettingChange)
-ICALL(ENV_17, "internalGetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable)
-ICALL(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath)
-ICALL(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome)
+HANDLES(ICALL(ENV_17, "internalGetEnvironmentVariable_native", ves_icall_System_Environment_GetEnvironmentVariable_native))
+HANDLES(ICALL(ENV_18, "internalGetGacPath", ves_icall_System_Environment_GetGacPath))
+HANDLES(ICALL(ENV_19, "internalGetHome", ves_icall_System_Environment_InternalGetHome))
 ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set)
 
 ICALL_TYPE(GC, "System.GC", GC_0)
@@ -403,7 +403,7 @@ ICALL(MONOIO_32, "get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparat
 ICALL(MONOIO_33, "get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar)
 
 ICALL_TYPE(IOPATH, "System.IO.Path", IOPATH_1)
-ICALL(IOPATH_1, "get_temp_path", ves_icall_System_IO_get_temp_path)
+HANDLES(ICALL(IOPATH_1, "get_temp_path", ves_icall_System_IO_get_temp_path))
 
 ICALL_TYPE(IOSELECTOR, "System.IOSelector", IOSELECTOR_1)
 ICALL(IOSELECTOR_1, "Add", ves_icall_System_IOSelector_Add)
@@ -494,7 +494,7 @@ ICALL(OBJ_2, "InternalGetHashCode", mono_object_hash)
 ICALL(OBJ_3, "MemberwiseClone", ves_icall_System_Object_MemberwiseClone)
 
 ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_1a)
-ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId)
+HANDLES(ICALL(ASSEM_1a, "GetAotId", ves_icall_System_Reflection_Assembly_GetAotId))
 ICALL(ASSEM_2, "GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly)
 ICALL(ASSEM_3, "GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly)
 ICALL(ASSEM_4, "GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly)
@@ -509,7 +509,7 @@ ICALL(ASSEM_12, "GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_
 ICALL(ASSEM_13, "GetTypes", ves_icall_System_Reflection_Assembly_GetTypes)
 ICALL(ASSEM_14, "InternalGetAssemblyName", ves_icall_System_Reflection_Assembly_InternalGetAssemblyName)
 ICALL(ASSEM_15, "InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType)
-ICALL(ASSEM_16, "InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion)
+HANDLES(ICALL(ASSEM_16, "InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion))
 ICALL(ASSEM_17, "LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom)
 ICALL(ASSEM_18, "LoadPermissions", ves_icall_System_Reflection_Assembly_LoadPermissions)
 
@@ -519,7 +519,7 @@ ICALL(ASSEM_21, "get_ReflectionOnly", ves_icall_System_Reflection_Assembly_get_R
 ICALL(ASSEM_22, "get_code_base", ves_icall_System_Reflection_Assembly_get_code_base)
 ICALL(ASSEM_23, "get_fullname", ves_icall_System_Reflection_Assembly_get_fullName)
 ICALL(ASSEM_24, "get_global_assembly_cache", ves_icall_System_Reflection_Assembly_get_global_assembly_cache)
-ICALL(ASSEM_25, "get_location", ves_icall_System_Reflection_Assembly_get_location)
+HANDLES(ICALL(ASSEM_25, "get_location", ves_icall_System_Reflection_Assembly_get_location))
 ICALL(ASSEM_26, "load_with_partial_name", ves_icall_System_Reflection_Assembly_load_with_partial_name)
 
 ICALL_TYPE(ASSEMN, "System.Reflection.AssemblyName", ASSEMN_0)
@@ -598,7 +598,7 @@ ICALL(MBASE_4, "GetMethodFromHandleInternalType_native", ves_icall_System_Reflec
 ICALL_TYPE(MODULE, "System.Reflection.Module", MODULE_1)
 ICALL(MODULE_1, "Close", ves_icall_System_Reflection_Module_Close)
 ICALL(MODULE_2, "GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType)
-ICALL(MODULE_3, "GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal)
+HANDLES(ICALL(MODULE_3, "GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal))
 ICALL(MODULE_14, "GetHINSTANCE", ves_icall_System_Reflection_Module_GetHINSTANCE)
 ICALL(MODULE_4, "GetMDStreamVersion", ves_icall_System_Reflection_Module_GetMDStreamVersion)
 ICALL(MODULE_5, "GetPEKind", ves_icall_System_Reflection_Module_GetPEKind)
@@ -796,8 +796,8 @@ ICALL(RT_18, "MakePointerType", ves_icall_RuntimeType_MakePointerType)
 HANDLES(ICALL(RT_19, "getFullName", ves_icall_System_RuntimeType_getFullName))
 ICALL(RT_21, "get_DeclaringMethod", ves_icall_RuntimeType_get_DeclaringMethod)
 ICALL(RT_22, "get_DeclaringType", ves_icall_RuntimeType_get_DeclaringType)
-ICALL(RT_23, "get_Name", ves_icall_RuntimeType_get_Name)
-ICALL(RT_24, "get_Namespace", ves_icall_RuntimeType_get_Namespace)
+HANDLES(ICALL(RT_23, "get_Name", ves_icall_RuntimeType_get_Name))
+HANDLES(ICALL(RT_24, "get_Namespace", ves_icall_RuntimeType_get_Namespace))
 ICALL(RT_25, "get_core_clr_security_level", vell_icall_RuntimeType_get_core_clr_security_level)
 ICALL(RT_26, "make_array_type", ves_icall_RuntimeType_make_array_type)
 ICALL(RT_27, "make_byref_type", ves_icall_RuntimeType_make_byref_type)
index 44ac525412d0fc974f43fdd2df2f0055b0ee5364..8c9eecc2f0379b551fdbdcc79ada4bb3082e7a16 100644 (file)
@@ -111,8 +111,6 @@ extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
 
 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
 
-TYPED_HANDLE_DECL (MonoReflectionType);
-
 /* Lazy class loading functions */
 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
@@ -2638,37 +2636,38 @@ ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
        return ret;
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_RuntimeType_get_Name (MonoReflectionType *type)
+ICALL_EXPORT MonoStringHandle
+ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
 {
-       MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (type->type);
+       MonoDomain *domain = mono_domain_get ();
+       MonoType *type = MONO_HANDLE_RAW(reftype)->type; 
+       MonoClass *klass = mono_class_from_mono_type (type);
 
-       if (type->type->byref) {
+       if (type->byref) {
                char *n = g_strdup_printf ("%s&", klass->name);
-               MonoString *res = mono_string_new (domain, n);
+               MonoStringHandle res = mono_string_new_handle (domain, n, error);
 
                g_free (n);
 
                return res;
        } else {
-               return mono_string_new (domain, klass->name);
+               return mono_string_new_handle (domain, klass->name, error);
        }
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_RuntimeType_get_Namespace (MonoReflectionType *type)
+ICALL_EXPORT MonoStringHandle
+ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
 {
        MonoDomain *domain = mono_domain_get (); 
-       MonoClass *klass = mono_class_from_mono_type (type->type);
+       MonoClass *klass = mono_class_from_mono_type_handle (type);
 
        while (klass->nested_in)
                klass = klass->nested_in;
 
        if (klass->name_space [0] == '\0')
-               return NULL;
+               return NULL_HANDLE_STRING;
        else
-               return mono_string_new (domain, klass->name_space);
+               return mono_string_new_handle (domain, klass->name_space, error);
 }
 
 ICALL_EXPORT gint32
@@ -4542,15 +4541,12 @@ ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname,
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
-       MonoString *res;
-
-       res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
-
-       return res;
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
+       MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
+       return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
 }
 
 ICALL_EXPORT MonoBoolean
@@ -4559,12 +4555,13 @@ ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly
        return assembly->assembly->ref_only;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (assembly); 
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
+       MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
 
-       return mono_string_new (domain, assembly->assembly->image->version);
+       return mono_string_new_handle (domain, assembly->image->version, error);
 }
 
 ICALL_EXPORT MonoReflectionMethod*
@@ -4619,8 +4616,8 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAss
        return result;
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Assembly_GetAotId ()
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
 {
        int i;
        guint8 aotid_sum = 0;
@@ -4636,8 +4633,11 @@ ves_icall_System_Reflection_Assembly_GetAotId ()
 
        if (aotid_sum == 0)
                return NULL;
-       
-       return mono_string_new (domain, mono_guid_to_string((guint8*) aotid));
+
+       gchar *guid = mono_guid_to_string((guint8*) aotid);
+       MonoStringHandle res = mono_string_new_handle (domain, guid, error);
+       g_free (guid);
+       return res;
 }
 
 static MonoObject*
@@ -5219,7 +5219,7 @@ ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gbool
                return NULL_HANDLE_STRING;
        }
 
-       res = mono_string_new_handle (domain, name);
+       res = mono_string_new_handle (domain, name, error);
        g_free (name);
 
        return res;
@@ -5703,13 +5703,14 @@ ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
                mono_image_close (module->image);*/
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (module); 
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
+       MonoImage *image = MONO_HANDLE_RAW (refmodule)->image;
 
-       g_assert (module->image);
-       return mono_string_new (domain, module->image->guid);
+       g_assert (image);
+       return mono_string_new_handle (domain, image->guid, error);
 }
 
 ICALL_EXPORT gpointer
@@ -6541,27 +6542,20 @@ ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
 #endif
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
 {
-       MonoError error;
        const gchar *value;
-       gchar *utf8_name;
 
-       if (name == NULL)
-               return NULL;
+       if (utf8_name == NULL)
+               return NULL_HANDLE_STRING;
 
-       utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
        value = g_getenv (utf8_name);
 
-       g_free (utf8_name);
-
        if (value == 0)
-               return NULL;
+               return NULL_HANDLE_STRING;
        
-       return mono_string_new (mono_domain_get (), value);
+       return mono_string_new_handle (mono_domain_get (), value, error);
 }
 
 /*
@@ -6760,10 +6754,10 @@ ves_icall_System_Environment_Exit (int result)
        exit (result);
 }
 
-ICALL_EXPORT MonoString*
-ves_icall_System_Environment_GetGacPath (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_GetGacPath (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
+       return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
 }
 
 ICALL_EXPORT MonoString*
@@ -6864,10 +6858,10 @@ ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_Environment_InternalGetHome (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_Environment_InternalGetHome (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), g_get_home_dir ());
+       return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
 }
 
 static const char *encodings [] = {
@@ -7117,10 +7111,10 @@ ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClas
        }
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_IO_get_temp_path (void)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_IO_get_temp_path (MonoError *error)
 {
-       return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
+       return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
 }
 
 #ifndef PLATFORM_NO_DRIVEINFO
@@ -7238,17 +7232,18 @@ get_bundled_app_config (void)
        return mono_string_new (mono_domain_get (), app_config);
 }
 
-static MonoString *
-get_bundled_machine_config (void)
+/* this is an icall */
+static MonoStringHandle
+get_bundled_machine_config (MonoError *error)
 {
        const gchar *machine_config;
 
        machine_config = mono_get_machine_config ();
 
        if (!machine_config)
-               return NULL;
+               return NULL_HANDLE_STRING;
 
-       return mono_string_new (mono_domain_get (), machine_config);
+       return mono_string_new_handle (mono_domain_get (), machine_config, error);
 }
 
 ICALL_EXPORT MonoString *
index 1f114033b5f5275b87c2a9a0bf9d78215827c7bb..a28e3d63fd99148d6aa19de0075ac55e615b59ab 100644 (file)
@@ -7,6 +7,7 @@
 #include <mono/metadata/mempool.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/threads-types.h>
+#include <mono/metadata/handle.h>
 #include <mono/io-layer/io-layer.h>
 #include "mono/utils/mono-compiler.h"
 #include "mono/utils/mono-error.h"
@@ -262,6 +263,9 @@ struct _MonoReflectionType {
        MonoType  *type;
 };
 
+/* Safely access System.Type from native code */
+TYPED_HANDLE_DECL (MonoReflectionType);
+
 /* This corresponds to System.RuntimeType */
 typedef struct {
        MonoReflectionType type;
@@ -808,6 +812,9 @@ struct _MonoReflectionAssembly {
        MonoString *name;
 };
 
+/* Safely access System.Reflection.Assembly from native code */
+TYPED_HANDLE_DECL (MonoReflectionAssembly);
+
 typedef struct {
        MonoReflectionType *utype;
        MonoArray *values;
@@ -1097,6 +1104,9 @@ struct _MonoReflectionModule {
        guint32 token;
 };
 
+/* Safely access System.Reflection.Module from native code */
+TYPED_HANDLE_DECL (MonoReflectionModule);
+
 typedef struct {
        MonoReflectionModule module;
        MonoDynamicImage *dynamic_image;
index 46afc75793748ed0a2e6ade041bf8ee71e517809..967867149caa4c79eaea873cd615b16ee230bd95 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef __MONO_METADATA_REFLECTION_INTERNALS_H__
 #define __MONO_METADATA_REFLECTION_INTERNALS_H__
 
+#include <mono/metadata/object-internals.h>
 #include <mono/metadata/reflection.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/utils/mono-compiler.h>
@@ -90,5 +91,8 @@ mono_module_file_get_object_checked (MonoDomain *domain, MonoImage *image, int t
 MonoReflectionMethodBody*
 mono_method_body_get_object_checked (MonoDomain *domain, MonoMethod *method, MonoError *error);
 
+MonoClass *
+mono_class_from_mono_type_handle (MonoReflectionTypeHandle h);
+
 
 #endif /* __MONO_METADATA_REFLECTION_INTERNALS_H__ */
index 66d02568805aac1477b5e536463ce890e973083f..0a5ea615a03f73a95bfc4822f98dd4307a265158 100644 (file)
@@ -2863,3 +2863,14 @@ mono_reflection_assembly_get_assembly (MonoReflectionAssembly *refassembly)
        return refassembly->assembly;
 }
 
+/**
+ * mono_class_from_mono_type_handle:
+ * @reftype: the System.Type handle
+ *
+ * Returns the MonoClass* corresponding to the given type.
+ */
+MonoClass*
+mono_class_from_mono_type_handle (MonoReflectionTypeHandle reftype)
+{
+       return mono_class_from_mono_type (MONO_HANDLE_RAW (reftype)->type);
+}