Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mono] UnsafeAccessor: Support ambiguous method match #89217

Merged
merged 10 commits into from
Jul 25, 2023
47 changes: 3 additions & 44 deletions src/mono/mono/metadata/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,31 +403,6 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk
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)
Expand All @@ -441,7 +416,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con

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) {
Expand All @@ -466,7 +441,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
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;
}
}
Expand Down Expand Up @@ -514,7 +489,7 @@ find_method_in_class (MonoClass *klass, const char *name, const char *qname, con
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;
}
Expand Down Expand Up @@ -972,22 +947,6 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp
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)
{
Expand Down
10 changes: 8 additions & 2 deletions src/mono/mono/metadata/marshal-lightweight.c
Original file line number Diff line number Diff line change
Expand Up @@ -2446,7 +2446,10 @@ emit_unsafe_accessor_ctor_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor_m
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;
}
Expand Down Expand Up @@ -2491,7 +2494,10 @@ emit_unsafe_accessor_method_wrapper (MonoMethodBuilder *mb, MonoMethod *accessor
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;
}
Expand Down
9 changes: 9 additions & 0 deletions src/mono/mono/metadata/metadata-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,15 @@ gboolean mono_metadata_generic_inst_equal (gconstpointer ka, gconstpointer
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,
Expand Down
Loading