return field;
}
-static gboolean
-mono_metadata_signature_vararg_match (MonoMethodSignature *sig1, MonoMethodSignature *sig2)
-{
- int i;
-
- if (sig1->hasthis != sig2->hasthis ||
- sig1->sentinelpos != sig2->sentinelpos)
- return FALSE;
-
- for (i = 0; i < sig1->sentinelpos; i++) {
- MonoType *p1 = sig1->params[i];
- MonoType *p2 = sig2->params[i];
-
- /*if (p1->attrs != p2->attrs)
- return FALSE;
- */
- if (!mono_metadata_type_equal (p1, p2))
- return FALSE;
- }
-
- if (!mono_metadata_type_equal (sig1->ret, sig2->ret))
- return FALSE;
- return TRUE;
-}
-
static MonoMethod *
find_method_in_class (MonoClass *klass, const char *name, const char *qname, const char *fqname,
MonoMethodSignature *sig, MonoClass *from_class, MonoError *error)
MonoImage *klass_image = m_class_get_image (klass);
/* FIXME: !mono_class_is_ginst (from_class) condition causes test failures. */
- if (m_class_get_type_token (klass) && !image_is_dynamic (klass_image) && !m_class_get_methods (klass) && !m_class_get_rank (klass) && klass == from_class && !mono_class_is_ginst (from_class)) {
+ if (m_class_get_type_token (klass) && !image_is_dynamic (klass_image) && !m_class_get_methods (klass) && !m_class_get_rank (klass) && klass == from_class && !mono_class_is_ginst (from_class) && (sig->call_convention != MONO_CALL_VARARG)) {
int first_idx = mono_class_get_first_method_idx (klass);
int mcount = mono_class_get_method_count (klass);
for (i = 0; i < mcount; ++i) {
other_sig = mono_method_signature_checked (method, error);
if (!is_ok (error)) //bail out if we hit a loader error
return NULL;
- if (other_sig && (sig->call_convention != MONO_CALL_VARARG) && mono_metadata_signature_equal (sig, other_sig))
+ if (other_sig && mono_metadata_signature_equal (sig, other_sig))
return method;
}
}
continue;
if (sig->call_convention == MONO_CALL_VARARG) {
- if (mono_metadata_signature_vararg_match (sig, msig)) {
+ if (mono_metadata_signature_equal_vararg (sig, msig)) {
matched = TRUE;
break;
}
return NULL;
}
-MonoMethod*
-mono_unsafe_accessor_find_ctor (MonoClass *in_class, MonoMethodSignature *sig, MonoClass *from_class, MonoError *error)
-{
- // This doesn't work for constructors because find_method explicitly disallows ".ctor" and ".cctor"
- //return find_method (in_class, /*ic*/NULL, name, sig, from_class, error);
- return find_method_in_class (in_class, ".ctor", /*qname*/NULL, /*fqname*/NULL, sig, from_class, error);
-}
-
-MonoMethod*
-mono_unsafe_accessor_find_method (MonoClass *in_class, const char *name, MonoMethodSignature *sig, MonoClass *from_class, MonoError *error)
-{
- // This doesn't work for constructors because find_method explicitly disallows ".ctor" and ".cctor"
- return find_method (in_class, /*ic*/NULL, name, sig, from_class, error);
-}
-
-
static MonoMethod *
method_from_methodspec (MonoImage *image, MonoGenericContext *context, guint32 idx, MonoError *error)
{
MonoClass *in_class = mono_class_is_ginst (target_class) ? mono_class_get_generic_class (target_class)->container_class : target_class;
MonoMethod *target_method = mono_unsafe_accessor_find_ctor (in_class, member_sig, target_class, find_method_error);
if (!is_ok (find_method_error) || target_method == NULL) {
- emit_missing_method_error (mb, find_method_error, "constructor");
+ if (mono_error_get_error_code (find_method_error) == MONO_ERROR_GENERIC)
+ mono_mb_emit_exception_for_error (mb, find_method_error);
+ else
+ emit_missing_method_error (mb, find_method_error, "constructor");
mono_error_cleanup (find_method_error);
return;
}
else
target_method = mono_unsafe_accessor_find_ctor (in_class, member_sig, target_class, find_method_error);
if (!is_ok (find_method_error) || target_method == NULL) {
- emit_missing_method_error (mb, find_method_error, member_name);
+ if (mono_error_get_error_code (find_method_error) == MONO_ERROR_GENERIC)
+ mono_mb_emit_exception_for_error (mb, find_method_error);
+ else
+ emit_missing_method_error (mb, find_method_error, member_name);
mono_error_cleanup (find_method_error);
return;
}
gboolean
mono_metadata_signature_equal_no_ret (MonoMethodSignature *sig1, MonoMethodSignature *sig2);
+gboolean
+mono_metadata_signature_equal_ignore_custom_modifier (MonoMethodSignature *sig1, MonoMethodSignature *sig2);
+
+gboolean
+mono_metadata_signature_equal_vararg (MonoMethodSignature *sig1, MonoMethodSignature *sig2);
+
+gboolean
+mono_metadata_signature_equal_vararg_ignore_custom_modifier (MonoMethodSignature *sig1, MonoMethodSignature *sig2);
+
MONO_API void
mono_metadata_field_info_with_mempool (
MonoImage *meta,
MonoGenericContext context;
} MonoInflatedMethodSignature;
+enum {
+ MONO_TYPE_EQ_FLAGS_SIG_ONLY = 1,
+ MONO_TYPE_EQ_FLAG_IGNORE_CMODS = 2,
+};
+
static gboolean do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer *container, gboolean transient,
const char *ptr, const char **rptr, MonoError *error);
-static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only);
+static gboolean do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, int equiv_flags);
static gboolean mono_metadata_class_equal (MonoClass *c1, MonoClass *c2, gboolean signature_only);
-static gboolean mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, gboolean signature_only);
+static gboolean mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, int equiv_flags);
static gboolean _mono_metadata_generic_class_equal (const MonoGenericClass *g1, const MonoGenericClass *g2,
gboolean signature_only);
static void free_generic_inst (MonoGenericInst *ginst);
if (a->is_open != b->is_open || a->type_argc != b->type_argc)
return FALSE;
for (guint i = 0; i < a->type_argc; ++i) {
- if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], signature_only))
+ if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], signature_only ? MONO_TYPE_EQ_FLAGS_SIG_ONLY : 0))
return FALSE;
}
return TRUE;
return mono_metadata_class_equal (c1_type->data.klass, c2_type->data.klass, signature_only);
if (signature_only &&
(c1_type->type == MONO_TYPE_ARRAY) && (c2_type->type == MONO_TYPE_ARRAY))
- return do_mono_metadata_type_equal (c1_type, c2_type, signature_only);
+ return do_mono_metadata_type_equal (c1_type, c2_type, signature_only ? MONO_TYPE_EQ_FLAGS_SIG_ONLY : 0);
if (signature_only &&
(c1_type->type == MONO_TYPE_PTR) && (c2_type->type == MONO_TYPE_PTR))
- return do_mono_metadata_type_equal (c1_type->data.type, c2_type->data.type, signature_only);
+ return do_mono_metadata_type_equal (c1_type->data.type, c2_type->data.type, signature_only ? MONO_TYPE_EQ_FLAGS_SIG_ONLY : 0);
if (signature_only &&
(c1_type->type == MONO_TYPE_FNPTR) && (c2_type->type == MONO_TYPE_FNPTR))
- return mono_metadata_fnptr_equal (c1_type->data.method, c2_type->data.method, signature_only);
+ return mono_metadata_fnptr_equal (c1_type->data.method, c2_type->data.method, signature_only ? MONO_TYPE_EQ_FLAGS_SIG_ONLY : 0);
return FALSE;
}
+static int
+mono_metadata_check_call_convention_category (unsigned int call_convention)
+{
+ switch (call_convention) {
+ case MONO_CALL_DEFAULT:
+ return 1;
+ case MONO_CALL_C:
+ case MONO_CALL_STDCALL:
+ case MONO_CALL_THISCALL:
+ case MONO_CALL_FASTCALL:
+ case MONO_CALL_UNMANAGED_MD:
+ return 2;
+ case MONO_CALL_VARARG:
+ return 3;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
static gboolean
-mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, gboolean signature_only)
+mono_metadata_fnptr_equal (MonoMethodSignature *s1, MonoMethodSignature *s2, int equiv_flags)
{
gpointer iter1 = 0, iter2 = 0;
if (s1 == s2)
return TRUE;
- if (s1->call_convention != s2->call_convention)
- return FALSE;
+
+ if ((equiv_flags & MONO_TYPE_EQ_FLAG_IGNORE_CMODS) == 0) {
+ if (s1->call_convention != s2->call_convention)
+ return FALSE;
+ } else {
+ if (mono_metadata_check_call_convention_category (s1->call_convention) != mono_metadata_check_call_convention_category (s2->call_convention))
+ return FALSE;
+ }
+
if (s1->sentinelpos != s2->sentinelpos)
return FALSE;
if (s1->hasthis != s2->hasthis)
return FALSE;
if (s1->explicit_this != s2->explicit_this)
return FALSE;
- if (! do_mono_metadata_type_equal (s1->ret, s2->ret, signature_only))
+ if (! do_mono_metadata_type_equal (s1->ret, s2->ret, equiv_flags))
return FALSE;
if (s1->param_count != s2->param_count)
return FALSE;
if (t1 == NULL || t2 == NULL)
return (t1 == t2);
- if (! do_mono_metadata_type_equal (t1, t2, signature_only))
+ if (! do_mono_metadata_type_equal (t1, t2, equiv_flags))
return FALSE;
}
}
if (cm1_required != cm2_required)
return FALSE;
- if (!do_mono_metadata_type_equal (cm1_type, cm2_type, signature_only))
+ if (!do_mono_metadata_type_equal (cm1_type, cm2_type, signature_only ? MONO_TYPE_EQ_FLAGS_SIG_ONLY : 0))
return FALSE;
}
return TRUE;
* Returns: #TRUE if @t1 and @t2 are equal.
*/
static gboolean
-do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, gboolean signature_only)
+do_mono_metadata_type_equal (MonoType *t1, MonoType *t2, int equiv_flags)
{
if (t1->type != t2->type || m_type_is_byref (t1) != m_type_is_byref (t2))
return FALSE;
gboolean cmod_reject = FALSE;
- if (t1->has_cmods != t2->has_cmods)
- cmod_reject = TRUE;
- else if (t1->has_cmods && t2->has_cmods) {
- cmod_reject = !mono_metadata_custom_modifiers_equal (t1, t2, signature_only);
+ if ((equiv_flags & MONO_TYPE_EQ_FLAG_IGNORE_CMODS) == 0) {
+ if (t1->has_cmods != t2->has_cmods)
+ cmod_reject = TRUE;
+ else if (t1->has_cmods && t2->has_cmods) {
+ cmod_reject = !mono_metadata_custom_modifiers_equal (t1, t2, (equiv_flags & MONO_TYPE_EQ_FLAGS_SIG_ONLY) != 0);
+ }
}
gboolean result = FALSE;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS:
case MONO_TYPE_SZARRAY:
- result = mono_metadata_class_equal (t1->data.klass, t2->data.klass, signature_only);
+ result = mono_metadata_class_equal (t1->data.klass, t2->data.klass, (equiv_flags & MONO_TYPE_EQ_FLAGS_SIG_ONLY) != 0);
break;
case MONO_TYPE_PTR:
- result = do_mono_metadata_type_equal (t1->data.type, t2->data.type, signature_only);
+ result = do_mono_metadata_type_equal (t1->data.type, t2->data.type, equiv_flags);
break;
case MONO_TYPE_ARRAY:
if (t1->data.array->rank != t2->data.array->rank)
result = FALSE;
else
- result = mono_metadata_class_equal (t1->data.array->eklass, t2->data.array->eklass, signature_only);
+ result = mono_metadata_class_equal (t1->data.array->eklass, t2->data.array->eklass, (equiv_flags & MONO_TYPE_EQ_FLAGS_SIG_ONLY) != 0);
break;
case MONO_TYPE_GENERICINST:
result = _mono_metadata_generic_class_equal (
- t1->data.generic_class, t2->data.generic_class, signature_only);
+ t1->data.generic_class, t2->data.generic_class, (equiv_flags & MONO_TYPE_EQ_FLAGS_SIG_ONLY) != 0);
break;
case MONO_TYPE_VAR:
result = mono_metadata_generic_param_equal_internal (
- t1->data.generic_param, t2->data.generic_param, signature_only);
+ t1->data.generic_param, t2->data.generic_param, (equiv_flags & MONO_TYPE_EQ_FLAGS_SIG_ONLY) != 0);
break;
case MONO_TYPE_MVAR:
result = mono_metadata_generic_param_equal_internal (
- t1->data.generic_param, t2->data.generic_param, signature_only);
+ t1->data.generic_param, t2->data.generic_param, (equiv_flags & MONO_TYPE_EQ_FLAGS_SIG_ONLY) != 0);
break;
case MONO_TYPE_FNPTR:
- result = mono_metadata_fnptr_equal (t1->data.method, t2->data.method, signature_only);
+ result = mono_metadata_fnptr_equal (t1->data.method, t2->data.method, equiv_flags);
break;
default:
g_error ("implement type compare for %0x!", t1->type);
gboolean
mono_metadata_type_equal (MonoType *t1, MonoType *t2)
{
- return do_mono_metadata_type_equal (t1, t2, FALSE);
+ return do_mono_metadata_type_equal (t1, t2, 0);
}
/**
gboolean
mono_metadata_type_equal_full (MonoType *t1, MonoType *t2, gboolean signature_only)
{
- return do_mono_metadata_type_equal (t1, t2, signature_only);
+ return do_mono_metadata_type_equal (t1, t2, signature_only ? MONO_TYPE_EQ_FLAGS_SIG_ONLY : 0);
}
enum {
SIG_EQUIV_FLAG_NO_RET = 1,
+ SIG_EQUIV_FLAG_IGNORE_CMODS = 2,
};
gboolean
return signature_equiv (sig1, sig2, SIG_EQUIV_FLAG_NO_RET);
}
+gboolean
+mono_metadata_signature_equal_ignore_custom_modifier (MonoMethodSignature *sig1, MonoMethodSignature *sig2)
+{
+ return signature_equiv (sig1, sig2, SIG_EQUIV_FLAG_IGNORE_CMODS);
+}
gboolean
signature_equiv (MonoMethodSignature *sig1, MonoMethodSignature *sig2, int equiv_flags)
if (sig1->generic_param_count != sig2->generic_param_count)
return FALSE;
+ int flag = MONO_TYPE_EQ_FLAGS_SIG_ONLY | (((equiv_flags & SIG_EQUIV_FLAG_IGNORE_CMODS) != 0) ? MONO_TYPE_EQ_FLAG_IGNORE_CMODS : 0);
+
/*
* We're just comparing the signatures of two methods here:
*
/* if (p1->attrs != p2->attrs)
return FALSE;
*/
- if (!do_mono_metadata_type_equal (p1, p2, TRUE))
+ if (!do_mono_metadata_type_equal (p1, p2, flag))
return FALSE;
}
if ((equiv_flags & SIG_EQUIV_FLAG_NO_RET) != 0)
return TRUE;
- if (!do_mono_metadata_type_equal (sig1->ret, sig2->ret, TRUE))
+ if (!do_mono_metadata_type_equal (sig1->ret, sig2->ret, flag))
+ return FALSE;
+ return TRUE;
+}
+
+gboolean
+signature_equiv_vararg (MonoMethodSignature *sig1, MonoMethodSignature *sig2, int equiv_flags);
+
+gboolean
+mono_metadata_signature_equal_vararg (MonoMethodSignature *sig1, MonoMethodSignature *sig2)
+{
+ return signature_equiv_vararg (sig1, sig2, 0);
+}
+
+gboolean
+mono_metadata_signature_equal_vararg_ignore_custom_modifier (MonoMethodSignature *sig1, MonoMethodSignature *sig2)
+{
+ return signature_equiv_vararg (sig1, sig2, SIG_EQUIV_FLAG_IGNORE_CMODS);
+}
+
+gboolean
+signature_equiv_vararg (MonoMethodSignature *sig1, MonoMethodSignature *sig2, int equiv_flags)
+{
+ int i;
+
+ if (sig1->hasthis != sig2->hasthis ||
+ sig1->sentinelpos != sig2->sentinelpos)
+ return FALSE;
+
+ int flag = MONO_TYPE_EQ_FLAGS_SIG_ONLY | (((equiv_flags & SIG_EQUIV_FLAG_IGNORE_CMODS) != 0) ? MONO_TYPE_EQ_FLAG_IGNORE_CMODS : 0);
+
+ for (i = 0; i < sig1->sentinelpos; i++) {
+ MonoType *p1 = sig1->params[i];
+ MonoType *p2 = sig2->params[i];
+
+ /*if (p1->attrs != p2->attrs)
+ return FALSE;
+ */
+ if (!do_mono_metadata_type_equal (p1, p2, flag))
+ return FALSE;
+ }
+
+ if (!do_mono_metadata_type_equal (sig1->ret, sig2->ret, flag))
return FALSE;
return TRUE;
}
g_assert (mono_error_get_error_code (error) == MONO_ERROR_GENERIC && "Unsupported error code.");
/* Have to copy the message because it will be referenced from JITed code while the MonoError may be freed. */
char *msg = mono_mb_strdup (mb, mono_error_get_message (error));
- mono_mb_emit_exception_full (mb, "System", mono_error_get_exception_name (error), msg);
+ mono_mb_emit_exception_full (mb, mono_error_get_exception_name_space (error), mono_error_get_exception_name (error), msg);
}
/**
#include "config.h"
#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "mono/metadata/metadata.h"
+#include "mono/metadata/image.h"
+#include "mono/metadata/tokentype.h"
+#include "mono/metadata/metadata-internals.h"
+#include "mono/metadata/class-init.h"
+#include "mono/metadata/class-internals.h"
+#include "mono/utils/mono-error-internals.h"
#include "mono/metadata/unsafe-accessor.h"
-#include "mono/utils/mono-compiler.h"
-MONO_EMPTY_SOURCE_FILE (unsafe_accessor)
+
+
+static MonoMethod *
+find_method_simple (MonoClass *klass, const char *name, const char *qname, const char *fqname,
+ MonoMethodSignature *sig, MonoClass *from_class, gboolean ignore_cmods, MonoError *error)
+{
+ MonoMethod *method_maybe = NULL;
+
+ /* Search directly in the metadata to avoid calling setup_methods () */
+ error_init (error);
+
+ MonoImage *klass_image = m_class_get_image (klass);
+ /* FIXME: !mono_class_is_ginst (from_class) condition causes test failures. */
+ if (m_class_get_type_token (klass) && !image_is_dynamic (klass_image) && !m_class_get_methods (klass) && !m_class_get_rank (klass) && klass == from_class && !mono_class_is_ginst (from_class)) {
+ int first_idx = mono_class_get_first_method_idx (klass);
+ int mcount = mono_class_get_method_count (klass);
+ for (int i = 0; i < mcount; ++i) {
+ guint32 cols [MONO_METHOD_SIZE];
+ MonoMethod *method;
+ const char *m_name;
+ MonoMethodSignature *other_sig;
+
+ mono_metadata_decode_table_row (klass_image, MONO_TABLE_METHOD, first_idx + i, cols, MONO_METHOD_SIZE);
+
+ m_name = mono_metadata_string_heap (klass_image, cols [MONO_METHOD_NAME]);
+
+ if (!((fqname && !strcmp (m_name, fqname)) ||
+ (qname && !strcmp (m_name, qname)) ||
+ (name && !strcmp (m_name, name))))
+ continue;
+
+ method = mono_get_method_checked (klass_image, MONO_TOKEN_METHOD_DEF | (first_idx + i + 1), klass, NULL, error);
+ if (!is_ok (error)) //bail out if we hit a loader error
+ return NULL;
+
+ // Check method signature
+ if (method) {
+ other_sig = mono_method_signature_checked (method, error);
+ if (!is_ok (error)) //bail out if we hit a loader error
+ return NULL;
+ if (other_sig) {
+ gboolean found = ignore_cmods ? mono_metadata_signature_equal_ignore_custom_modifier (sig, other_sig) : mono_metadata_signature_equal (sig, other_sig);
+ if (found) {
+ if (method_maybe != NULL) {
+ if (ignore_cmods) {
+ MonoMethod *precise_match = find_method_simple (klass, name, qname, fqname, sig, from_class, FALSE, error);
+ if (precise_match)
+ return precise_match;
+ }
+ mono_error_set_generic_error (error, "System.Reflection", "AmbiguousMatchException", "Ambiguity in binding of UnsafeAccessorAttribute.");
+ return NULL;
+ }
+ method_maybe = method;
+ }
+ }
+ }
+ }
+ return method_maybe;
+ }
+
+ return NULL;
+}
+
+typedef struct MethodLookupResultInfo {
+ int i;
+ MonoMethod *m;
+ gboolean matched;
+} MethodLookupResultInfo;
+
+static MethodLookupResultInfo *
+find_method_slow (MonoClass *klass, const char *name, const char *qname, const char *fqname,
+ MonoMethodSignature *sig, gboolean ignore_cmods, MonoError *error)
+{
+ gpointer iter = NULL;
+ MethodLookupResultInfo *result = (MethodLookupResultInfo *)g_malloc0 (sizeof (MethodLookupResultInfo));
+ int i = -1;
+ MonoMethod *m = NULL;
+ gboolean matched = FALSE;
+ result->i = i;
+ result->m = m;
+ result->matched = matched;
+
+ /* FIXME: metadata-update iterating using
+ * mono_class_get_methods will break if `m` is NULL. Need to
+ * reconcile with the `if (!m)` "we must cope" comment below.
+ */
+ while ((m = mono_class_get_methods (klass, &iter))) {
+ i++;
+ MonoMethodSignature *msig;
+
+ /* We must cope with failing to load some of the types. */
+ if (!m)
+ continue;
+
+ if (!((fqname && !strcmp (m->name, fqname)) ||
+ (qname && !strcmp (m->name, qname)) ||
+ (name && !strcmp (m->name, name))))
+ continue;
+ msig = mono_method_signature_checked (m, error);
+ if (!is_ok (error)) //bail out if we hit a loader error
+ return NULL;
+
+ if (!msig)
+ continue;
+
+ gboolean found = FALSE;
+ if (ignore_cmods)
+ found = sig->call_convention == MONO_CALL_VARARG ? mono_metadata_signature_equal_vararg_ignore_custom_modifier (sig, msig) : mono_metadata_signature_equal_ignore_custom_modifier (sig, msig);
+ else
+ found = sig->call_convention == MONO_CALL_VARARG ? mono_metadata_signature_equal_vararg (sig, msig) : mono_metadata_signature_equal (sig, msig);
+
+ if (found) {
+ if (matched) {
+ if (ignore_cmods) {
+ MethodLookupResultInfo *precise_match = find_method_slow (klass, name, qname, fqname, sig, FALSE, error);
+ if (precise_match->m)
+ return precise_match;
+ }
+ mono_error_set_generic_error (error, "System.Reflection", "AmbiguousMatchException", "Ambiguity in binding of UnsafeAccessorAttribute.");
+ return NULL;
+ }
+ matched = TRUE;
+ result->i = i;
+ result->m = m;
+ result->matched = matched;
+ }
+ }
+
+ return result;
+}
+
+static MonoMethod *
+find_method_in_class_unsafe_accessor (MonoClass *klass, const char *name, const char *qname, const char *fqname,
+ MonoMethodSignature *sig, MonoClass *from_class, gboolean ignore_cmods, MonoError *error)
+{
+ MonoMethod *method = NULL;
+ if (sig->call_convention != MONO_CALL_VARARG)
+ method = find_method_simple (klass, name, qname, fqname, sig, from_class, ignore_cmods, error);
+ if (method)
+ return method;
+ if (!is_ok(error) && mono_error_get_error_code (error) == MONO_ERROR_GENERIC)
+ return NULL;
+
+ mono_class_setup_methods (klass); /* FIXME don't swallow the error here. */
+ /*
+ We can't fail lookup of methods otherwise the runtime will fail with MissingMethodException instead of TypeLoadException.
+ See mono/tests/generic-type-load-exception.2.il
+ FIXME we should better report this error to the caller
+ */
+ if (!m_class_get_methods (klass) || mono_class_has_failure (klass)) {
+ ERROR_DECL (cause_error);
+ mono_error_set_for_class_failure (cause_error, klass);
+ mono_error_set_type_load_class (error, klass, "Could not find method '%s' due to a type load error: %s", name, mono_error_get_message (cause_error));
+ mono_error_cleanup (cause_error);
+ return NULL;
+ }
+
+ MethodLookupResultInfo *result = find_method_slow (klass, name, qname, fqname, sig, ignore_cmods, error);
+ if (!is_ok(error) && mono_error_get_error_code (error) == MONO_ERROR_GENERIC)
+ return NULL;
+
+ int mcount = mono_class_get_method_count (klass);
+
+ g_assert (result != NULL);
+ if (result->matched) {
+ if (result->i < mcount)
+ return mono_class_get_method_by_index (from_class, result->i);
+ else if (result->m != NULL) {
+ // FIXME: metadata-update: hack
+ // it's from a metadata-update, probably
+ MonoMethod * m = mono_class_inflate_generic_method_full_checked (
+ result->m, from_class, mono_class_get_context (from_class), error);
+ mono_error_assert_ok (error);
+ g_assert (m != NULL);
+ g_assert (m->klass == from_class);
+ g_assert (m->is_inflated);
+ return m;
+ }
+ }
+
+ g_free (result);
+ return NULL;
+}
+
+MonoMethod*
+mono_unsafe_accessor_find_ctor (MonoClass *in_class, MonoMethodSignature *sig, MonoClass *from_class, MonoError *error)
+{
+ return find_method_in_class_unsafe_accessor (in_class, ".ctor", /*qname*/NULL, /*fqname*/NULL, sig, from_class, TRUE, error);
+}
+
+MonoMethod*
+mono_unsafe_accessor_find_method (MonoClass *in_class, const char *name, MonoMethodSignature *sig, MonoClass *from_class, MonoError *error)
+{
+ // This doesn't work for constructors because find_method explicitly disallows ".ctor" and ".cctor"
+ return find_method_in_class_unsafe_accessor (in_class, name, /*qname*/NULL, /*fqname*/NULL, sig, from_class, TRUE, error);
+}
const char*
mono_error_get_exception_name (MonoError *oerror);
+const char*
+mono_error_get_exception_name_space (MonoError *oerror);
+
void
mono_error_set_specific (MonoError *error, int error_code, const char *missing_method);
return error->exception_name;
}
+const char*
+mono_error_get_exception_name_space (MonoError *oerror)
+{
+ MonoErrorInternal *error = (MonoErrorInternal*)oerror;
+
+ if (error->error_code == MONO_ERROR_NONE)
+ return NULL;
+
+ return error->exception_name_space;
+}
+
/*Return a pointer to the internal error message, might be NULL.
Caller should not release it.*/
const char*
private void _mvv() {}
// The "init" is important to have here - custom modifier test.
+ // The signature of set_Prop is
+ // instance void modreq([System.Runtime]System.Runtime.CompilerServices.IsExternalInit) set_Prop ( string 'value')
private string Prop { get; init; }
// Used to validate ambiguity is handled via custom modifiers.
}
[Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/86040", TestRuntimes.Mono)]
public static void Verify_IgnoreCustomModifier()
{
Console.WriteLine($"Running {nameof(Verify_IgnoreCustomModifier)}");
}
[Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/86040", TestRuntimes.Mono)]
public static void Verify_UnmanagedCallConvBitAreTreatedAsCustomModifiersAndIgnored()
{
Console.WriteLine($"Running {nameof(Verify_UnmanagedCallConvBitAreTreatedAsCustomModifiersAndIgnored)}");
}
[Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/86040", TestRuntimes.Mono)]
public static void Verify_ManagedUnmanagedFunctionPointersDontMatch()
{
Console.WriteLine($"Running {nameof(Verify_ManagedUnmanagedFunctionPointersDontMatch)}");
}
[Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/89212", TestRuntimes.Mono)]
public static void Verify_InheritanceMethodResolution()
{
Console.WriteLine($"Running {nameof(Verify_InheritanceMethodResolution)}");
}
[Fact]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/86040", TestRuntimes.Mono)]
public static void Verify_InvalidTargetUnsafeAccessorAmbiguousMatch()
{
Console.WriteLine($"Running {nameof(Verify_InvalidTargetUnsafeAccessorAmbiguousMatch)}");