Skip to content

Commit

Permalink
[mono][wasm] Handle delegates decorated with [UnmanagedFunctionPointe… (
Browse files Browse the repository at this point in the history
dotnet#77709)

* [mono][wasm] Handle delegates decorated with [UnmanagedFunctionPointer] in
the interp-to-native generator.

Fixes dotnet#76930.

* Update src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs

Co-authored-by: Ankit Jain <radical@gmail.com>

* Update src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs

Co-authored-by: Ankit Jain <radical@gmail.com>

* Update src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs

Co-authored-by: Ankit Jain <radical@gmail.com>

Co-authored-by: Ankit Jain <radical@gmail.com>
  • Loading branch information
vargaz and radical authored Nov 2, 2022
1 parent f43d5e3 commit bdd67af
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ private void CollectPInvokes(List<PInvoke> pinvokes, List<PInvokeCallback> callb
}
}

if (HasAttribute(type, "System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute"))
{
var method = type.GetMethod("Invoke");

if (method != null)
{
string? signature = SignatureMapper.MethodToSignature(method!);
if (signature == null)
throw new NotSupportedException($"Unsupported parameter type in method '{type.FullName}.{method.Name}'");


Log.LogMessage(MessageImportance.Low, $"Adding pinvoke signature {signature} for method '{type.FullName}.{method.Name}'");
signatures.Add(signature);
}
}

void CollectPInvokesForMethod(MethodInfo method)
{
if ((method.Attributes & MethodAttributes.PinvokeImpl) != 0)
Expand Down Expand Up @@ -151,6 +167,29 @@ static bool MethodHasCallbackAttributes(MethodInfo method)
}
}

private static bool HasAttribute(MemberInfo element, params string[] attributeNames)
{
foreach (CustomAttributeData cattr in CustomAttributeData.GetCustomAttributes(element))
{
try
{
for (int i = 0; i < attributeNames.Length; ++i)
{
if (cattr.AttributeType.FullName == attributeNames [i] ||
cattr.AttributeType.Name == attributeNames[i])
{
return true;
}
}
}
catch
{
// Assembly not found, ignore
}
}
return false;
}

private void EmitPInvokeTable(StreamWriter w, Dictionary<string, string> modules, List<PInvoke> pinvokes)
{
w.WriteLine("// GENERATED FILE, DO NOT MODIFY");
Expand Down

0 comments on commit bdd67af

Please sign in to comment.