[exdoc] Handle punctuation better in code formatting.
[mono.git] / mono / metadata / icall.c
index 6f76a3250a9e96b5cd2bb5664d5885cf0e4aa80b..99fe267bff477ba0df5866f7a4751a80aa8aa317 100644 (file)
@@ -1,5 +1,5 @@
-/*
- * icall.c:
+/**
+ * \file
  *
  * Authors:
  *   Dietmar Maurer (dietmar@ximian.com)
@@ -582,6 +582,11 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *
        if (mono_error_set_pending_exception (&error))
                return NULL;
 
+       if (klass->element_class->byval_arg.type == MONO_TYPE_VOID) {
+               mono_set_pending_exception (mono_get_exception_not_supported ("Arrays of System.Void are not supported."));
+               return NULL;
+       }
+
        if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
                /* vectors are not the same as one dimensional arrays with no-zero bounds */
                bounded = TRUE;
@@ -1793,46 +1798,36 @@ vell_icall_get_method_attributes (MonoMethod *method)
 }
 
 ICALL_EXPORT void
-ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
+ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info, MonoError *error)
 {
-       MonoError error;
-       MonoReflectionType *rt;
        MonoDomain *domain = mono_domain_get ();
-       MonoMethodSignature* sig;
 
-       sig = mono_method_signature_checked (method, &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return;
-       }
+       MonoMethodSignature* sig = mono_method_signature_checked (method, error);
+       return_if_nok (error);
 
-       rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return;
-       }
+       MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &method->klass->byval_arg, error);
+       return_if_nok (error);
 
-       MONO_STRUCT_SETREF (info, parent, rt);
+       MONO_STRUCT_SETREF (info, parent, MONO_HANDLE_RAW (rt));
 
-       rt = mono_type_get_object_checked (domain, sig->ret, &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return;
-       }
+       MONO_HANDLE_ASSIGN (rt, mono_type_get_object_handle (domain, sig->ret, error));
+       return_if_nok (error);
 
-       MONO_STRUCT_SETREF (info, ret, rt);
+       MONO_STRUCT_SETREF (info, ret, MONO_HANDLE_RAW (rt));
 
        info->attrs = method->flags;
        info->implattrs = method->iflags;
+       guint32 callconv;
        if (sig->call_convention == MONO_CALL_DEFAULT)
-               info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
+               callconv = sig->sentinelpos >= 0 ? 2 : 1;
        else {
                if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
-                       info->callconv = 2;
+                       callconv = 2;
                else
-                       info->callconv = 1;
+                       callconv = 1;
        }
-       info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6); 
+       callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
+       info->callconv = callconv;
 }
 
 ICALL_EXPORT MonoArrayHandle
@@ -2173,60 +2168,63 @@ typedef enum {
 } PInfo;
 
 ICALL_EXPORT void
-ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
+ves_icall_MonoPropertyInfo_get_property_info (MonoReflectionPropertyHandle property, MonoPropertyInfo *info, PInfo req_info, MonoError *error)
 {
-       MonoError error;
-       MonoReflectionType *rt;
-       MonoReflectionMethod *rm;
-       MonoDomain *domain = mono_object_domain (property); 
-       const MonoProperty *pproperty = property->property;
+       error_init (error);
+       MonoDomain *domain = MONO_HANDLE_DOMAIN (property); 
+       const MonoProperty *pproperty = MONO_HANDLE_GETVAL (property, property);
 
        if ((req_info & PInfo_ReflectedType) != 0) {
-               rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return;
+               MonoClass *klass = MONO_HANDLE_GETVAL (property, klass);
+               MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
+               return_if_nok (error);
 
-               MONO_STRUCT_SETREF (info, parent, rt);
+               MONO_STRUCT_SETREF (info, parent, MONO_HANDLE_RAW (rt));
        }
        if ((req_info & PInfo_DeclaringType) != 0) {
-               rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
-               if (mono_error_set_pending_exception (&error))
-                       return;
+               MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &pproperty->parent->byval_arg, error);
+               return_if_nok (error);
 
-               MONO_STRUCT_SETREF (info, declaring_type, rt);
+               MONO_STRUCT_SETREF (info, declaring_type, MONO_HANDLE_RAW (rt));
        }
 
-       if ((req_info & PInfo_Name) != 0)
-               MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
+       if ((req_info & PInfo_Name) != 0) {
+               MonoStringHandle name = mono_string_new_handle (domain, pproperty->name, error);
+               return_if_nok (error);
+
+               MONO_STRUCT_SETREF (info, name, MONO_HANDLE_RAW (name));
+       }
 
        if ((req_info & PInfo_Attributes) != 0)
                info->attrs = pproperty->attrs;
 
        if ((req_info & PInfo_GetMethod) != 0) {
+               MonoClass *property_klass = MONO_HANDLE_GETVAL (property, klass);
+               MonoReflectionMethodHandle rm;
                if (pproperty->get &&
                    (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
-                    pproperty->get->klass == property->klass)) {
-                       rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return;
+                    pproperty->get->klass == property_klass)) {
+                       rm = mono_method_get_object_handle (domain, pproperty->get, property_klass, error);
+                       return_if_nok (error);
                } else {
-                       rm = NULL;
+                       rm = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
                }
 
-               MONO_STRUCT_SETREF (info, get, rm);
+               MONO_STRUCT_SETREF (info, get, MONO_HANDLE_RAW (rm));
        }
        if ((req_info & PInfo_SetMethod) != 0) {
+               MonoClass *property_klass = MONO_HANDLE_GETVAL (property, klass);
+               MonoReflectionMethodHandle rm;
                if (pproperty->set &&
                    (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
-                    pproperty->set->klass == property->klass)) {
-                       rm =  mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
-                       if (mono_error_set_pending_exception (&error))
-                               return;
+                    pproperty->set->klass == property_klass)) {
+                       rm =  mono_method_get_object_handle (domain, pproperty->set, property_klass, error);
+                       return_if_nok (error);
                } else {
-                       rm = NULL;
+                       rm = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
                }
 
-               MONO_STRUCT_SETREF (info, set, rm);
+               MONO_STRUCT_SETREF (info, set, MONO_HANDLE_RAW (rm));
        }
        /* 
         * There may be other methods defined for properties, though, it seems they are not exposed 
@@ -2578,6 +2576,18 @@ ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionTypeHandle ref_type, Mono
        return (!type->byref && (((type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8)) || (type->type == MONO_TYPE_I) || (type->type == MONO_TYPE_U)));
 }
 
+ICALL_EXPORT MonoBoolean
+ves_icall_RuntimeTypeHandle_HasReferences (MonoReflectionTypeHandle ref_type, MonoError *error)
+{
+       error_init (error);
+       MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
+       MonoClass *klass;
+
+       klass = mono_class_from_mono_type (type);
+       mono_class_init (klass);
+       return klass->has_references;
+}
+
 ICALL_EXPORT MonoBoolean
 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionTypeHandle ref_type, MonoError *error)
 {
@@ -6092,6 +6102,7 @@ check_for_invalid_type (MonoClass *klass, MonoError *error)
        name = mono_type_get_full_name (klass);
        mono_error_set_type_load_name (error, name, g_strdup (""), "");
 }
+
 ICALL_EXPORT MonoReflectionTypeHandle
 ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int rank, MonoError *error)
 {
@@ -6109,6 +6120,11 @@ ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int ra
        else
                aklass = mono_bounded_array_class_get (klass, rank, TRUE);
 
+       if (mono_class_has_failure (aklass)) {
+               mono_error_set_for_class_failure (error, aklass);
+               return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
+       }
+
        MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
        return mono_type_get_object_handle (domain, &aklass->byval_arg, error);
 }
@@ -7269,10 +7285,20 @@ ves_icall_MonoMethod_get_base_method (MonoReflectionMethodHandle m, gboolean def
 
        MonoMethod *base = mono_method_get_base_method (method, definition, error);
        return_val_if_nok (error, MONO_HANDLE_CAST (MonoReflectionMethod, NULL_HANDLE));
-       if (base == method)
-               return m;
-       else
-               return mono_method_get_object_handle (mono_domain_get (), base, NULL, error);
+       if (base == method) {
+               /* we want to short-circuit and return 'm' here. But we should
+                  return the same method object that
+                  mono_method_get_object_handle, below would return.  Since
+                  that call takes NULL for the reftype argument, it will take
+                  base->klass as the reflected type for the MonoMethod.  So we
+                  need to check that m also has base->klass as the reflected
+                  type. */
+               MonoReflectionTypeHandle orig_reftype = MONO_HANDLE_NEW_GET (MonoReflectionType, m, reftype);
+               MonoClass *orig_klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (orig_reftype, type));
+               if (base->klass == orig_klass)
+                       return m;
+       }
+       return mono_method_get_object_handle (mono_domain_get (), base, NULL, error);
 }
 
 ICALL_EXPORT MonoStringHandle
@@ -8069,12 +8095,12 @@ mono_icall_cleanup (void)
 
 /**
  * mono_add_internal_call:
- * @name: method specification to surface to the managed world
- * @method: pointer to a C method to invoke when the method is called
+ * \param name method specification to surface to the managed world
+ * \param method pointer to a C method to invoke when the method is called
  *
- * This method surfaces the C function pointed by @method as a method
+ * This method surfaces the C function pointed by \p method as a method
  * that has been surfaced in managed code with the method specified in
- * @name as an internal call.
+ * \p name as an internal call.
  *
  * Internal calls are surfaced to all app domains loaded and they are
  * accessibly by a type with the specified name.
@@ -8253,11 +8279,10 @@ no_icall_table (void)
 
 /**
  * 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
+ * \param method the method to look up
+ * \param uses_handles out argument if method needs handles around managed objects.
+ * \returns a pointer to the icall code for the given method.  If
+ * \p 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.