[BTLS]: Add the native BTLS sources.
[mono.git] / mono / metadata / icall.c
index 395bf739f84f091f87e06fbd03500b1069eefedf..27bafb33291f7151a889412b11f11102bf7f4883 100644 (file)
@@ -43,7 +43,9 @@
 #include <mono/metadata/threadpool-ms-io.h>
 #include <mono/metadata/monitor.h>
 #include <mono/metadata/reflection.h>
+#include <mono/metadata/image-internals.h>
 #include <mono/metadata/assembly.h>
+#include <mono/metadata/assembly-internals.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/exception-internals.h>
 #include <mono/metadata/runtime.h>
 #include <mono/metadata/file-mmap.h>
 #include <mono/metadata/seq-points-data.h>
+#include <mono/metadata/handle.h>
+#include <mono/metadata/w32mutex.h>
+#include <mono/metadata/w32semaphore.h>
+#include <mono/metadata/w32event.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/monobitset.h>
 #include <mono/utils/mono-time.h>
 #include <sys/utsname.h>
 #endif
 
+#if HAVE_BTLS
+#include <btls/btls-ssl.h>
+#include <btls/btls-bio.h>
+#include <btls/btls-error.h>
+#include <btls/btls-key.h>
+#include <btls/btls-pkcs12.h>
+#include <btls/btls-x509-crl.h>
+#include <btls/btls-x509-chain.h>
+#include <btls/btls-x509-lookup.h>
+#include <btls/btls-x509-lookup-mono.h>
+#include <btls/btls-x509-name.h>
+#include <btls/btls-x509-revoked.h>
+#include <btls/btls-x509-store-ctx.h>
+#include <btls/btls-x509-verify-param.h>
+#endif
+
 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
 
 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
@@ -980,11 +1002,6 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStac
        /* if we have no info we are optimistic and assume there is enough room */
        if (!stack_addr)
                return TRUE;
-#ifdef HOST_WIN32
-       // FIXME: Windows dynamically extends the stack, so stack_addr might be close
-       // to the current sp
-       return TRUE;
-#endif
        current = (guint8 *)&stack_addr;
        if (current > stack_addr) {
                if ((current - stack_addr) < min_size)
@@ -1210,100 +1227,6 @@ ves_icall_System_Object_GetType (MonoObject *obj)
        return ret;
 }
 
-ICALL_EXPORT gint32
-ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance)
-{
-       MONO_CHECK_ARG_NULL (obj, 0);
-       
-       MonoError error;
-       gint32 result = mono_image_create_token (mb->dynamic_image, obj, create_open_instance, TRUE, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-ICALL_EXPORT gint32
-ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
-                                       MonoReflectionMethod *method,
-                                       MonoArray *opt_param_types)
-{
-       MONO_CHECK_ARG_NULL (method, 0);
-       
-       MonoError error;
-       gint32 result = mono_image_create_method_token (
-               mb->dynamic_image, (MonoObject *) method, opt_param_types, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-ICALL_EXPORT void
-ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
-{
-       MonoError error;
-       mono_image_create_pefile (mb, file, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-ICALL_EXPORT void
-ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
-{
-       MonoError error;
-       mono_image_build_metadata (mb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-ICALL_EXPORT void
-ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
-{
-       mono_image_register_token (mb->dynamic_image, token, obj);
-}
-
-ICALL_EXPORT MonoObject*
-ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
-{
-       MonoObject *obj;
-
-       mono_loader_lock ();
-       obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
-       mono_loader_unlock ();
-
-       return obj;
-}
-
-ICALL_EXPORT MonoReflectionModule*
-ves_icall_System_Reflection_Emit_AssemblyBuilder_InternalAddModule (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
-{
-       MonoError error;
-       MonoReflectionModule *result = mono_image_load_module_dynamic (ab, fileName, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-
-/**
- * ves_icall_System_Reflection_Emit_TypeBuilder_create_generic_class:
- * @tb: a TypeBuilder object
- *
- * (icall)
- * Creates the generic class after all generic parameters have been added.
- */
-ICALL_EXPORT void
-ves_icall_System_Reflection_Emit_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
-{
-       MonoError error;
-       (void) mono_reflection_create_generic_class (tb, &error);
-       mono_error_set_pending_exception (&error);
-}
-
-#ifndef DISABLE_REFLECTION_EMIT
-ICALL_EXPORT MonoArray*
-ves_icall_System_Reflection_Emit_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
-{
-       MonoError error;
-       MonoArray *result = mono_reflection_get_custom_attrs_blob_checked (assembly, ctor, ctorArgs, properties, propValues, fields, fieldValues, &error);
-       mono_error_set_pending_exception (&error);
-       return result;
-}
-#endif
-
 static gboolean
 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
 {
@@ -1541,6 +1464,21 @@ ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
        g_ptr_array_free (ptr_array, TRUE);
 }
 
+ICALL_EXPORT void
+ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
+{
+       g_free (c_str);
+}
+
+ICALL_EXPORT char*
+ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
+{
+       MonoError error;
+       char *res = mono_string_to_utf8_checked (s, &error);
+       mono_error_set_pending_exception (&error);
+       return res;
+}
+
 /* System.TypeCode */
 typedef enum {
        TYPECODE_EMPTY,
@@ -2714,37 +2652,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
@@ -2941,19 +2880,6 @@ ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
        return is_generic_parameter (type->type);
 }
 
-ICALL_EXPORT MonoBoolean
-ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
-{
-       return is_generic_parameter (tb->type.type);
-}
-
-ICALL_EXPORT void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
-                                                                          MonoReflectionType *t)
-{
-       enumtype->type = t->type;
-}
-
 ICALL_EXPORT MonoReflectionMethod*
 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type, 
                                                    MonoReflectionMethod* generic)
@@ -3790,29 +3716,29 @@ enum {
 };
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
 {
        MonoError error;
-       MonoDomain *domain; 
        MonoClass *startklass, *klass;
        int match;
        gpointer iter;
-       char *utf8_name = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;    
        MonoClassField *field;
 
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
                return g_ptr_array_new ();
        }
 
+       mono_error_init (&error);
+
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
        klass = startklass = mono_class_from_mono_type (type->type);
 
        GPtrArray *ptr_array = g_ptr_array_sized_new (16);
        
 handle_parent: 
        if (mono_class_has_failure (klass)) {
-               mono_error_init (&error);
                mono_error_set_for_class_failure (&error, klass);
                goto fail;
        }
@@ -3846,29 +3772,18 @@ handle_parent:
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (utf8_name == NULL) {
-                               utf8_name = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto fail;
-                               compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-                       }
-
-                       if (compare_func (mono_field_get_name (field), utf8_name))
+               if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
                                continue;
-               }
 
                g_ptr_array_add (ptr_array, field);
        }
        if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
                goto handle_parent;
 
-       if (utf8_name != NULL)
-               g_free (utf8_name);
        return ptr_array;
 
 fail:
-       g_ptr_array_free (ptr_array, FALSE);
+       g_ptr_array_free (ptr_array, TRUE);
        mono_error_set_pending_exception (&error);
        return NULL;
 }
@@ -3998,28 +3913,18 @@ loader_error:
 }
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
+ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
 {
        MonoError error;
-       MonoDomain *domain; 
-       const char *mname = NULL;
        GPtrArray *method_array;
        MonoClass *klass;
 
        klass = mono_class_from_mono_type (type->type);
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
                return g_ptr_array_new ();
        }
 
-       if (name) {
-               mname = mono_string_to_utf8_checked (name, &error);
-               if (mono_error_set_pending_exception (&error))
-                   return NULL;
-       }
-
        method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
-       g_free ((char*)mname);
        mono_error_set_pending_exception (&error);
        return method_array;
 }
@@ -4146,7 +4051,7 @@ property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
 }
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case)
+ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
 {
        MonoError error;
        MonoClass *startklass, *klass;
@@ -4154,7 +4059,6 @@ ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, Mono
        MonoProperty *prop;
        int match;
        guint32 flags;
-       gchar *propname = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;
        gpointer iter;
        GHashTable *properties = NULL;
@@ -4168,12 +4072,7 @@ ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, Mono
        
        klass = startklass = mono_class_from_mono_type (type->type);
 
-       if (name != NULL) {
-               propname = mono_string_to_utf8_checked (name, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return NULL;
-               compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
-       }
+       compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
 
        res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
 
@@ -4181,8 +4080,10 @@ ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, Mono
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass))
+       if (mono_class_has_failure (klass)) {
+               mono_error_set_for_class_failure (&error, klass);
                goto loader_error;
+       }
 
        iter = NULL;
        while ((prop = mono_class_get_properties (klass, &iter))) {
@@ -4220,10 +4121,8 @@ handle_parent:
                        continue;
                match = 0;
 
-               if (name != NULL) {
-                       if (compare_func (propname, prop->name))
-                               continue;
-               }
+               if (propname != NULL && compare_func (propname, prop->name))
+                       continue;
                
                if (g_hash_table_lookup (properties, prop))
                        continue;
@@ -4236,20 +4135,14 @@ handle_parent:
                goto handle_parent;
 
        g_hash_table_destroy (properties);
-       g_free (propname);
 
        return res_array;
 
 
 loader_error:
-       if (mono_class_has_failure (klass))
-               mono_error_set_for_class_failure (&error, klass);
-
        if (properties)
                g_hash_table_destroy (properties);
-       if (name)
-               g_free (propname);
-       g_ptr_array_free (res_array, FALSE);
+       g_ptr_array_free (res_array, TRUE);
 
        mono_error_set_pending_exception (&error);
 
@@ -4272,7 +4165,7 @@ event_equal (MonoEvent *event1, MonoEvent *event2)
 }
 
 ICALL_EXPORT GPtrArray*
-ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
 {
        MonoError error;
        MonoClass *startklass, *klass;
@@ -4280,7 +4173,6 @@ ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *na
        MonoEvent *event;
        int match;
        gpointer iter;
-       char *utf8_name = NULL;
        int (*compare_func) (const char *s1, const char *s2) = NULL;    
        GHashTable *events = NULL;
        GPtrArray *res_array;
@@ -4291,6 +4183,8 @@ ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *na
 
        mono_error_init (&error);
 
+       compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
+
        res_array = g_ptr_array_sized_new (4);
 
        klass = startklass = mono_class_from_mono_type (type->type);
@@ -4299,8 +4193,10 @@ ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, MonoString *na
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass))
-               goto loader_error;
+       if (mono_class_has_failure (klass)) {
+               mono_error_set_for_class_failure (&error, klass);
+               goto failure;
+       }
 
        iter = NULL;
        while ((event = mono_class_get_events (klass, &iter))) {
@@ -4341,17 +4237,8 @@ handle_parent:
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (utf8_name == NULL) {
-                               utf8_name = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto failure;
-                               compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
-                       }
-
-                       if (compare_func (event->name, utf8_name))
-                               continue;
-               }               
+               if (utf8_name != NULL && compare_func (event->name, utf8_name))
+                       continue;
 
                if (g_hash_table_lookup (events, event))
                        continue;
@@ -4365,50 +4252,31 @@ handle_parent:
 
        g_hash_table_destroy (events);
 
-       if (utf8_name != NULL)
-               g_free (utf8_name);
-
        return res_array;
 
-loader_error:
-       if (mono_class_has_failure (klass))
-               mono_error_set_for_class_failure (&error, klass);
-
 failure:
-       
        if (events != NULL)
                g_hash_table_destroy (events);
-       if (utf8_name != NULL)
-               g_free (utf8_name);
 
-       g_ptr_array_free (res_array, FALSE);
+       g_ptr_array_free (res_array, TRUE);
 
        mono_error_set_pending_exception (&error);
        return NULL;
 }
 
-ICALL_EXPORT MonoArray*
-ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name, guint32 bflags)
+ICALL_EXPORT GPtrArray *
+ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
 {
-       MonoError error;
-       MonoReflectionType *rt;
-       MonoDomain *domain; 
        MonoClass *klass;
-       MonoArray *res = NULL;
-       int i, match;
+       int match;
        MonoClass *nested;
        gpointer iter;
-       char *str = NULL;
-       MonoPtrArray tmp_array;
-
-       mono_error_init (&error);
+       GPtrArray *res_array;
 
-       domain = ((MonoObject *)type)->vtable->domain;
        if (type->type->byref) {
-               MonoArray *result = mono_array_new_cached (domain, mono_defaults.runtimetype_class, 0, &error);
-               mono_error_set_pending_exception (&error);
-               return result;
+               return g_ptr_array_new ();
        }
+
        klass = mono_class_from_mono_type (type->type);
 
        /*
@@ -4423,7 +4291,8 @@ ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name
        if (klass->generic_class)
                klass = klass->generic_class->container_class;
 
-       mono_ptr_array_init (tmp_array, 1, MONO_ROOT_SOURCE_REFLECTION, "temporary reflection nested types list");
+       res_array = g_ptr_array_new ();
+       
        iter = NULL;
        while ((nested = mono_class_get_nested_types (klass, &iter))) {
                match = 0;
@@ -4437,39 +4306,13 @@ ves_icall_RuntimeType_GetNestedTypes (MonoReflectionType *type, MonoString *name
                if (!match)
                        continue;
 
-               if (name != NULL) {
-                       if (str == NULL) {
-                               str = mono_string_to_utf8_checked (name, &error);
-                               if (!is_ok (&error))
-                                       goto leave;
-                               mono_identifier_unescape_type_name_chars (str);
-                       }
-
-                       if (strcmp (nested->name, str))
+               if (str != NULL && strcmp (nested->name, str))
                                continue;
-               }
-
-               rt = mono_type_get_object_checked (domain, &nested->byval_arg, &error);
-               if (!is_ok (&error))
-                       goto leave;
 
-               mono_ptr_array_append (tmp_array, (MonoObject*) rt);
+               g_ptr_array_add (res_array, &nested->byval_arg);
        }
 
-       res = mono_array_new_cached (domain, mono_defaults.runtimetype_class, mono_ptr_array_size (tmp_array), &error);
-       if (!is_ok (&error))
-               goto leave;
-
-       for (i = 0; i < mono_ptr_array_size (tmp_array); ++i)
-               mono_array_setref (res, i, mono_ptr_array_get (tmp_array, i));
-
-leave:
-       mono_ptr_array_destroy (tmp_array);
-
-       g_free (str);
-
-       mono_error_set_pending_exception (&error);
-       return res;
+       return res_array;
 }
 
 ICALL_EXPORT MonoReflectionType*
@@ -4714,15 +4557,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
@@ -4731,12 +4571,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*
@@ -4791,8 +4632,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;
@@ -4808,8 +4649,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*
@@ -4999,8 +4843,8 @@ ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflection
                g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
                file_idx = impl >> MONO_IMPLEMENTATION_BITS;
 
-               module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
-               if (!module)
+               module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
+               if (mono_error_set_pending_exception (&error) || !module)
                        return NULL;
        }
        else
@@ -5200,7 +5044,9 @@ ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly
                        mono_array_setref (res, j, rm);
                }
                else {
-                       MonoImage *m = mono_image_load_file_for_image (image, i + 1);
+                       MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return NULL;
                        if (!m) {
                                MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
                                mono_set_pending_exception (mono_get_exception_file_not_found2 (NULL, fname));
@@ -5365,13 +5211,14 @@ ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
        return result;
 }
 
-ICALL_EXPORT MonoString *
-ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
-                                      gboolean assembly_qualified)
+ICALL_EXPORT MonoStringHandle
+ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
+                                                                                 gboolean assembly_qualified, MonoError *error)
 {
-       MonoDomain *domain = mono_object_domain (object); 
+       MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
+       MonoType *type = MONO_HANDLE_RAW (object)->type;
        MonoTypeNameFormat format;
-       MonoString *res;
+       MonoStringHandle res;
        gchar *name;
 
        if (full_name)
@@ -5381,16 +5228,16 @@ ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full
        else
                format = MONO_TYPE_NAME_FORMAT_REFLECTION;
  
-       name = mono_type_get_name_full (object->type, format);
+       name = mono_type_get_name_full (type, format);
        if (!name)
-               return NULL;
+               return NULL_HANDLE_STRING;
 
-       if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
+       if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
                g_free (name);
-               return NULL;
+               return NULL_HANDLE_STRING;
        }
 
-       res = mono_string_new (domain, name);
+       res = mono_string_new_handle (domain, name, error);
        g_free (name);
 
        return res;
@@ -5555,29 +5402,10 @@ ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assem
        return res;
 }
 
-ICALL_EXPORT void
-ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
+ICALL_EXPORT MonoAssemblyName *
+ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
 {
-       MonoError error;
-       gchar *absolute, *dirname;
-       MonoAssembly *mass = assembly->assembly;
-
-       /* XXX this is duplicated code to compute the codebase URI, unify it */
-       if (g_path_is_absolute (mass->image->name)) {
-               absolute = g_strdup (mass->image->name);
-               dirname = g_path_get_dirname (absolute);
-       } else {
-               absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
-               dirname = g_strdup (mass->basedir);
-       }
-
-       replace_shadow_path (mono_object_domain (assembly), dirname, &absolute);
-       g_free (dirname);
-
-       fill_reflection_assembly_name (mono_object_domain (assembly), aname, &mass->aname, absolute, TRUE, TRUE, TRUE, &error);
-       mono_error_set_pending_exception (&error);
-
-       g_free (absolute);
+       return &mass->aname;
 }
 
 ICALL_EXPORT void
@@ -5742,7 +5570,9 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
        /* Append data from all modules in the assembly */
        for (i = 0; i < table->rows; ++i) {
                if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
-                       MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
+                       MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return NULL;
                        if (loaded_image) {
                                MonoArray *ex2;
                                MonoArray *res2;
@@ -5843,35 +5673,18 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
        return res;
 }
 
-ICALL_EXPORT gboolean
-ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
+ICALL_EXPORT void
+ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname)
 {
-       MonoError error;
-       MonoAssemblyName aname;
-       MonoDomain *domain = mono_object_domain (name);
-       char *val;
-       gboolean is_version_defined;
-       gboolean is_token_defined;
-
-       aname.public_key = NULL;
-       val = mono_string_to_utf8_checked (assname, &error);
-       if (mono_error_set_pending_exception (&error))
-               return FALSE;
-
-       if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined)) {
-               g_free ((guint8*) aname.public_key);
-               g_free (val);
-               return FALSE;
-       }
-       
-       fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined, FALSE, is_token_defined, &error);
-       mono_error_set_pending_exception (&error);
+       mono_assembly_name_free (aname);
+}
 
-       mono_assembly_name_free (&aname);
-       g_free ((guint8*) aname.public_key);
-       g_free (val);
+ICALL_EXPORT gboolean
+ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
+{
+       *is_version_definited = *is_token_defined = FALSE;
 
-       return TRUE;
+       return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
 }
 
 ICALL_EXPORT MonoReflectionType*
@@ -5910,13 +5723,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
@@ -6314,77 +6128,6 @@ ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 t
        return res;
 }
 
-ICALL_EXPORT MonoReflectionType*
-ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
-{
-       MonoError error;
-       MonoReflectionType *ret;
-       MonoClass *klass;
-       int isbyref = 0, rank;
-       char *p;
-       char *str = mono_string_to_utf8_checked (smodifiers, &error);
-       if (mono_error_set_pending_exception (&error))
-               return NULL;
-
-       klass = mono_class_from_mono_type (tb->type.type);
-       p = str;
-       /* logic taken from mono_reflection_parse_type(): keep in sync */
-       while (*p) {
-               switch (*p) {
-               case '&':
-                       if (isbyref) { /* only one level allowed by the spec */
-                               g_free (str);
-                               return NULL;
-                       }
-                       isbyref = 1;
-                       p++;
-
-                       g_free (str);
-
-                       ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->this_arg, &error);
-                       mono_error_set_pending_exception (&error);
-
-                       return ret;
-               case '*':
-                       klass = mono_ptr_class_get (&klass->byval_arg);
-                       mono_class_init (klass);
-                       p++;
-                       break;
-               case '[':
-                       rank = 1;
-                       p++;
-                       while (*p) {
-                               if (*p == ']')
-                                       break;
-                               if (*p == ',')
-                                       rank++;
-                               else if (*p != '*') { /* '*' means unknown lower bound */
-                                       g_free (str);
-                                       return NULL;
-                               }
-                               ++p;
-                       }
-                       if (*p != ']') {
-                               g_free (str);
-                               return NULL;
-                       }
-                       p++;
-                       klass = mono_array_class_get (klass, rank);
-                       mono_class_init (klass);
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       g_free (str);
-
-       ret = mono_type_get_object_checked (mono_object_domain (tb), &klass->byval_arg, &error);
-       mono_error_set_pending_exception (&error);
-
-       return ret;
-}
-
 ICALL_EXPORT MonoBoolean
 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
 {
@@ -6490,6 +6233,7 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
        MonoObject *delegate;
        gpointer func;
        MonoMethod *method = info->method;
+       MonoMethodSignature *sig = mono_method_signature(method);
 
        mono_class_init_checked (delegate_class, &error);
        if (mono_error_set_pending_exception (&error))
@@ -6514,6 +6258,13 @@ ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, Mon
                }
        }
 
+       if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
+               if (!method->is_inflated) {
+                       mono_set_pending_exception(mono_get_exception_argument("method", " Cannot bind to the target method because its signature differs from that of the delegate type"));
+                       return NULL;
+               }
+       }
+
        delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
        if (mono_error_set_pending_exception (&error))
                return NULL;
@@ -6819,27 +6570,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);
 }
 
 /*
@@ -7038,10 +6782,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*
@@ -7142,10 +6886,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 [] = {
@@ -7216,7 +6960,7 @@ ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
        
        if (strstr (codepage, "utf_8") != NULL)
                *int_code_page |= 0x10000000;
-       free (codepage);
+       g_free (codepage);
        
        if (want_name && *int_code_page == -1)
                return mono_string_new (mono_domain_get (), cset);
@@ -7395,10 +7139,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
@@ -7516,17 +7260,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 *
@@ -7664,6 +7409,7 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
                klass = klass->generic_class->container_class;
        }
 
+retry:
        if (definition) {
                /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
                for (parent = klass->parent; parent != NULL; parent = parent->parent) {
@@ -7750,14 +7496,38 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definiti
        result = klass->vtable [slot];
        if (result == NULL) {
                /* It is an abstract method */
+               gboolean found = FALSE;
                gpointer iter = NULL;
-               while ((result = mono_class_get_methods (klass, &iter)))
-                       if (result->slot == slot)
+               while ((result = mono_class_get_methods (klass, &iter))) {
+                       if (result->slot == slot) {
+                               found = TRUE;
                                break;
+                       }
+               }
+               /* found might be FALSE if we looked in an abstract class
+                * that doesn't override an abstract method of its
+                * parent: 
+                *   abstract class Base {
+                *     public abstract void Foo ();
+                *   }
+                *   abstract class Derived : Base { }
+                *   class Child : Derived {
+                *     public override void Foo () { }
+                *  }
+                *
+                *  if m was Child.Foo and we ask for the base method,
+                *  then we get here with klass == Derived and found == FALSE
+                */
+               /* but it shouldn't be the case that if we're looking
+                * for the definition and didn't find a result; the
+                * loop above should've taken us as far as we could
+                * go! */
+               g_assert (!(definition && !found));
+               if (!found)
+                       goto retry;
        }
 
-       if (result == NULL)
-               return m;
+       g_assert (result != NULL);
 
        ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
        mono_error_set_pending_exception (&error);
@@ -8279,7 +8049,12 @@ ves_icall_Microsoft_Win32_NativeMethods_TerminateProcess (gpointer handle, gint3
 ICALL_EXPORT gint32
 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
 {
+#ifdef HOST_WIN32
        return WaitForInputIdle (handle, milliseconds);
+#else
+       /*TODO: Not implemented*/
+       return WAIT_TIMEOUT;
+#endif
 }
 
 ICALL_EXPORT MonoBoolean
@@ -8318,10 +8093,21 @@ ves_icall_Microsoft_Win32_NativeMethods_SetPriorityClass (gpointer handle, gint3
        return SetPriorityClass (handle, priorityClass);
 }
 
+ICALL_EXPORT MonoBoolean
+ves_icall_Mono_Btls_Provider_IsSupported (void)
+{
+#if HAVE_BTLS
+       return TRUE;
+#else
+       return FALSE;
+#endif
+}
+
 #ifndef DISABLE_ICALL_TABLES
 
 #define ICALL_TYPE(id,name,first)
 #define ICALL(id,name,func) Icall_ ## id,
+#define HANDLES(inner) inner
 
 enum {
 #include "metadata/icall-def.h"
@@ -8332,6 +8118,8 @@ enum {
 #undef ICALL
 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
 #define ICALL(id,name,func)
+#undef HANDLES
+#define HANDLES(inner) inner
 enum {
 #include "metadata/icall-def.h"
        Icall_type_num
@@ -8341,6 +8129,8 @@ enum {
 #undef ICALL
 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
 #define ICALL(id,name,func)
+#undef HANDLES
+#define HANDLES(inner) inner
 typedef struct {
        guint16 first_icall;
 } IcallTypeDesc;
@@ -8353,6 +8143,8 @@ icall_type_descs [] = {
 
 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
 
+#undef HANDLES
+#define HANDLES(inner) inner
 #undef ICALL_TYPE
 #define ICALL_TYPE(id,name,first)
 #undef ICALL
@@ -8424,6 +8216,8 @@ icall_names [] = {
 
 #endif /* !HAVE_ARRAY_ELEM_INIT */
 
+#undef HANDLES
+#define HANDLES(inner) inner
 #undef ICALL_TYPE
 #undef ICALL
 #define ICALL_TYPE(id,name,first)
@@ -8435,6 +8229,8 @@ icall_functions [] = {
 };
 
 #ifdef ENABLE_ICALL_SYMBOL_MAP
+#undef HANDLES
+#define HANDLES(inner) inner
 #undef ICALL_TYPE
 #undef ICALL
 #define ICALL_TYPE(id,name,first)
@@ -8446,6 +8242,19 @@ icall_symbols [] = {
 };
 #endif
 
+#undef ICALL_TYPE
+#undef ICALL
+#define ICALL_TYPE(id,name,first)
+#define ICALL(id,name,func) 0,
+#undef HANDLES
+#define HANDLES(inner) 1,
+static const guchar
+icall_uses_handles [] = {
+#include "metadata/icall-def.h"
+#undef ICALL
+#undef HANDLES
+};
+
 #endif /* DISABLE_ICALL_TABLES */
 
 static mono_mutex_t icall_mutex;
@@ -8566,13 +8375,31 @@ compare_method_imap (const void *key, const void *elem)
        return strcmp (key, method_name);
 }
 
-static gpointer
-find_method_icall (const IcallTypeDesc *imap, const char *name)
+static gsize
+find_slot_icall (const IcallTypeDesc *imap, const char *name)
 {
        const guint16 *nameslot = (const guint16 *)mono_binary_search (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
        if (!nameslot)
+               return -1;
+       return (nameslot - &icall_names_idx [0]);
+}
+
+static gboolean
+find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
+{
+       gsize slotnum = find_slot_icall (imap, name);
+       if (slotnum == -1)
+               return FALSE;
+       return (gboolean)icall_uses_handles [slotnum];
+}
+
+static gpointer
+find_method_icall (const IcallTypeDesc *imap, const char *name)
+{
+       gsize slotnum = find_slot_icall (imap, name);
+       if (slotnum == -1)
                return NULL;
-       return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
+       return (gpointer)icall_functions [slotnum];
 }
 
 static int
@@ -8600,13 +8427,31 @@ compare_method_imap (const void *key, const void *elem)
        return strcmp (key, *method_name);
 }
 
-static gpointer
-find_method_icall (const IcallTypeDesc *imap, const char *name)
+static gsize
+find_slot_icall (const IcallTypeDesc *imap, const char *name)
 {
        const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
        if (!nameslot)
+               return -1;
+       return nameslot - icall_names;
+}
+
+static gpointer
+find_method_icall (const IcallTypeDesc *imap, const char *name)
+{
+       gsize slotnum = find_slot_icall (imap, name);
+       if (slotnum == -1)
                return NULL;
-       return (gpointer)icall_functions [(nameslot - icall_names)];
+       return (gpointer)icall_functions [slotnum];
+}
+
+static gboolean
+find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
+{
+       gsize slotnum = find_slot_icall (imap, name);
+       if (slotnum == -1)
+               return FALSE;
+       return (gboolean)icall_uses_handles [slotnum];
 }
 
 static int
@@ -8658,8 +8503,19 @@ no_icall_table (void)
 }
 #endif
 
+/**
+ * mono_lookup_internal_call_full:
+ * @method: the method to look up
+ * @uses_handles: out argument if method needs handles around managed objects.
+ *
+ * Returns a pointer to the icall code for the given method.  If
+ * uses_handles is not NULL, it will be set to TRUE if the method
+ * needs managed objects wrapped using the infrastructure in handle.h
+ *
+ * If the method is not found, warns and returns NULL.
+ */
 gpointer
-mono_lookup_internal_call (MonoMethod *method)
+mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
 {
        char *sigstart;
        char *tmpsig;
@@ -8720,6 +8576,8 @@ mono_lookup_internal_call (MonoMethod *method)
 
        res = g_hash_table_lookup (icall_hash, mname);
        if (res) {
+               if (uses_handles)
+                       *uses_handles = FALSE;
                mono_icall_unlock ();;
                return res;
        }
@@ -8727,6 +8585,8 @@ mono_lookup_internal_call (MonoMethod *method)
        *sigstart = 0;
        res = g_hash_table_lookup (icall_hash, mname);
        if (res) {
+               if (uses_handles)
+                       *uses_handles = FALSE;
                mono_icall_unlock ();
                return res;
        }
@@ -8742,11 +8602,15 @@ mono_lookup_internal_call (MonoMethod *method)
 #else
        /* it wasn't found in the static call tables */
        if (!imap) {
+               if (uses_handles)
+                       *uses_handles = FALSE;
                mono_icall_unlock ();
                return NULL;
        }
        res = find_method_icall (imap, sigstart - mlen);
        if (res) {
+               if (uses_handles)
+                       *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
                mono_icall_unlock ();
                return res;
        }
@@ -8754,6 +8618,8 @@ mono_lookup_internal_call (MonoMethod *method)
        *sigstart = '(';
        res = find_method_icall (imap, sigstart - mlen);
        if (res) {
+               if (uses_handles)
+                       *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
                mono_icall_unlock ();
                return res;
        }
@@ -8772,6 +8638,12 @@ mono_lookup_internal_call (MonoMethod *method)
 #endif
 }
 
+gpointer
+mono_lookup_internal_call (MonoMethod *method)
+{
+       return mono_lookup_internal_call_full (method, NULL);
+}
+
 #ifdef ENABLE_ICALL_SYMBOL_MAP
 static int
 func_cmp (gconstpointer key, gconstpointer p)