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] Support UnsafeAccessorAttribute method calls with custom modifiers #89098

Closed
Tracked by #86040
lambdageek opened this issue Jul 18, 2023 · 3 comments · Fixed by #89217
Closed
Tracked by #86040

[mono] Support UnsafeAccessorAttribute method calls with custom modifiers #89098

lambdageek opened this issue Jul 18, 2023 · 3 comments · Fixed by #89217
Assignees
Milestone

Comments

@lambdageek
Copy link
Member

lambdageek commented Jul 18, 2023

Enable these disabled tests:

  • Verify_IgnoreCustomModifier
  • Verify_UnmanagedCallConvBitAreTreatedAsCustomModifiersAndIgnored
  • Verify_ManagedUnmanagedFunctionPointersDontMatch and
  • Verify_InvalidTargetUnsafeAccessorAmbiguousMatch

Part of #86040

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jul 18, 2023
@lambdageek lambdageek added area-AssemblyLoader-mono and removed area-VM-meta-mono untriaged New issue has not been triaged by the area owner labels Jul 18, 2023
@ghost
Copy link

ghost commented Jul 18, 2023

Tagging subscribers to this area:
See info in area-owners.md if you want to be subscribed.

Issue Details

Enable these disabled tests:

  • Verify_IgnoreCustomModifier
  • Verify_UnmanagedCallConvBitAreTreatedAsCustomModifiersAndIgnored
  • Verify_ManagedUnmanagedFunctionPointersDontMatch and
  • Verify_InvalidTargetUnsafeAccessorAmbiguousMatch
Author: lambdageek
Assignees: -
Labels:

untriaged, area-AssemblyLoader-mono, area-VM-meta-mono

Milestone: -

@lambdageek lambdageek added this to the 8.0.0 milestone Jul 18, 2023
@lambdageek
Copy link
Member Author

lambdageek commented Jul 18, 2023

The CoreCLR algorithm is

bool TrySetTargetMethod(
GenerationContext& cxt,
LPCUTF8 methodName,
bool ignoreCustomModifiers = true)
{
STANDARD_VM_CONTRACT;
_ASSERTE(methodName != NULL);
_ASSERTE(cxt.Kind == UnsafeAccessorKind::Constructor
|| cxt.Kind == UnsafeAccessorKind::Method
|| cxt.Kind == UnsafeAccessorKind::StaticMethod);
TypeHandle targetType = cxt.TargetType;
_ASSERTE(!targetType.IsTypeDesc());
MethodDesc* targetMaybe = NULL;
// Following the iteration pattern found in MemberLoader::FindMethod().
// Reverse order is recommended - see comments in MemberLoader::FindMethod().
MethodTable::MethodIterator iter(targetType.AsMethodTable());
iter.MoveToEnd();
for (; iter.IsValid(); iter.Prev())
{
MethodDesc* curr = iter.GetDeclMethodDesc();
// Check the target and current method match static/instance state.
if (cxt.IsTargetStatic != (!!curr->IsStatic()))
continue;
// Check for matching name
if (strcmp(methodName, curr->GetNameThrowing()) != 0)
continue;
// Check signature
MetaSig::CompareState state{};
state.IgnoreCustomModifiers = ignoreCustomModifiers;
if (!DoesMethodMatchUnsafeAccessorDeclaration(cxt, curr, state))
continue;
// Check if there is some ambiguity.
if (targetMaybe != NULL)
{
if (ignoreCustomModifiers)
{
// We have detected ambiguity when ignoring custom modifiers.
// Start over, but look for a match requiring custom modifiers
// to match precisely.
if (TrySetTargetMethod(cxt, methodName, false /* ignoreCustomModifiers */))
return true;
}
COMPlusThrow(kAmbiguousMatchException, W("Arg_AmbiguousMatchException_UnsafeAccessor"));
}
targetMaybe = curr;
}
cxt.TargetMethod = targetMaybe;
return cxt.TargetMethod != NULL;
}
(https://discord.com/channels/@me/769298323270008832/1130894020411924571)

Right now in Mono we piggyback on find_method_in_class in loader.c, but actually we should write a separate implementation to use in mono_unsafe_accessor_find_ctor and mono_unsafe_accessor_find_method that does the same two pass algorithm as CoreCLR that first tries ignoring custom modifiers and then doing an exact match.

MethodTable::MethodIterator iter(targetType.AsMethodTable()) in CoreCLR doesn't have an exact corresponding mechanism in Mono, I think (I think it traverses all the methods in the class hierarchy - is that right?) so we would need a loop using mono_class_get_methods() inside a second loop going up the hierarchy

@lambdageek
Copy link
Member Author

We will need to add a variant of mono_metadata_signature_equal that passes a new flag to signature_equiv: SIG_EQUIV_FLAG_IGNORE_CMODS and propagate that all the way down into the type equivalence code in metadata.c

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 24, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 25, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants