未验证 提交 f4e8005a 编写于 作者: M Marek Fišera 提交者: GitHub

[wasm] Log as warning in interop generator when method signature is not supported (#71477)

Introduce WASM0001 warning code for not supported pinvoke and icall signatures.
上级 4fac43b0
......@@ -32,7 +32,7 @@ internal sealed class IcallTableGenerator
// The runtime icall table should be generated using
// mono --print-icall-table
//
public IEnumerable<string> GenIcallTable(string? runtimeIcallTableFile, string[] assemblies, string? outputPath)
public IEnumerable<string> Generate(string? runtimeIcallTableFile, string[] assemblies, string? outputPath)
{
_icalls.Clear();
_signatures.Clear();
......@@ -146,7 +146,15 @@ private void ProcessType(Type type)
if ((method.GetMethodImplementationFlags() & MethodImplAttributes.InternalCall) == 0)
continue;
AddSignature(type, method);
try
{
AddSignature(type, method);
}
catch (Exception ex) when (ex is not LogAsErrorException)
{
Log.LogWarning(null, "WASM0001", "", "", 0, 0, 0, 0, $"Could not get icall, or callbacks for method '{method.Name}' because '{ex.Message}'");
continue;
}
var className = method.DeclaringType!.FullName!;
if (!_runtimeIcalls.ContainsKey(className))
......@@ -214,7 +222,7 @@ void AddSignature(Type type, MethodInfo method)
throw new LogAsErrorException($"Unsupported parameter type in method '{type.FullName}.{method.Name}'");
}
Log.LogMessage(MessageImportance.Normal, $"[icall] Adding signature {signature} for method '{type.FullName}.{method.Name}'");
Log.LogMessage(MessageImportance.Low, $"Adding icall signature {signature} for method '{type.FullName}.{method.Name}'");
_signatures.Add(signature);
}
}
......
......@@ -69,8 +69,8 @@ private void ExecuteInternal()
var icall = new IcallTableGenerator(Log);
IEnumerable<string> cookies = Enumerable.Concat(
pinvoke.GenPInvokeTable(PInvokeModules, Assemblies!, PInvokeOutputPath!),
icall.GenIcallTable(RuntimeIcallTableFile, Assemblies!, IcallOutputPath)
pinvoke.Generate(PInvokeModules, Assemblies!, PInvokeOutputPath!),
icall.Generate(RuntimeIcallTableFile, Assemblies!, IcallOutputPath)
);
var m2n = new InterpToNativeGenerator(Log);
......
......@@ -19,7 +19,7 @@ internal sealed class PInvokeTableGenerator
public PInvokeTableGenerator(TaskLoggingHelper log) => Log = log;
public IEnumerable<string> GenPInvokeTable(string[] pinvokeModules, string[] assemblies, string outputPath)
public IEnumerable<string> Generate(string[] pinvokeModules, string[] assemblies, string outputPath)
{
var modules = new Dictionary<string, string>();
foreach (var module in pinvokeModules)
......@@ -69,10 +69,9 @@ private void CollectPInvokes(List<PInvoke> pinvokes, List<PInvokeCallback> callb
{
CollectPInvokesForMethod(method);
}
catch (Exception ex)
catch (Exception ex) when (ex is not LogAsErrorException)
{
Log.LogMessage(MessageImportance.Low, $"Could not get pinvoke, or callbacks for method {method.Name}: {ex}");
continue;
Log.LogWarning(null, "WASM0001", "", "", 0, 0, 0, 0, $"Could not get pinvoke, or callbacks for method '{method.Name}' because '{ex.Message}'");
}
}
......@@ -88,10 +87,10 @@ void CollectPInvokesForMethod(MethodInfo method)
string? signature = SignatureMapper.MethodToSignature(method);
if (signature == null)
{
throw new LogAsErrorException($"Unsupported parameter type in method '{type.FullName}.{method.Name}'");
throw new NotSupportedException($"Unsupported parameter type in method '{type.FullName}.{method.Name}'");
}
Log.LogMessage(MessageImportance.Normal, $"[pinvoke] Adding signature {signature} for method '{type.FullName}.{method.Name}'");
Log.LogMessage(MessageImportance.Low, $"Adding pinvoke signature {signature} for method '{type.FullName}.{method.Name}'");
signatures.Add(signature);
}
......@@ -101,6 +100,7 @@ void CollectPInvokesForMethod(MethodInfo method)
{
if (cattr.AttributeType.FullName == "System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute" ||
cattr.AttributeType.Name == "MonoPInvokeCallbackAttribute")
callbacks.Add(new PInvokeCallback(method));
}
catch
......@@ -301,7 +301,8 @@ private static bool TryIsMethodGetParametersUnsupported(MethodInfo method, [NotN
if (TryIsMethodGetParametersUnsupported(pinvoke.Method, out string? reason))
{
Log.LogWarning($"Skipping the following DllImport because '{reason}'. {Environment.NewLine} {pinvoke.Method}");
Log.LogWarning(null, "WASM0001", "", "", 0, 0, 0, 0, $"Skipping pinvoke '{pinvoke.Method}' because '{reason}'.");
pinvoke.Skip = true;
return null;
}
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Xunit;
using Xunit.Abstractions;
......@@ -58,29 +59,32 @@ public static int Main(string[] args)
[BuildAndRun(host: RunHost.Chrome)]
public void DllImportWithFunctionPointersCompilesWithWarning(BuildArgs buildArgs, RunHost host, string id)
{
string code = @"
string code =
"""
using System;
using System.Runtime.InteropServices;
public class Test
{
public static int Main()
{
Console.WriteLine($""Main running"");
Console.WriteLine("Main running");
return 42;
}
[DllImport(""variadic"", EntryPoint=""sum"")]
[DllImport("variadic", EntryPoint="sum")]
public unsafe static extern int using_sum_one(delegate* unmanaged<char*, IntPtr, void> callback);
[DllImport(""variadic"", EntryPoint=""sum"")]
[DllImport("variadic", EntryPoint="sum")]
public static extern int sum_one(int a, int b);
}";
}
""";
(buildArgs, string output) = BuildForVariadicFunctionTests(code,
buildArgs with { ProjectName = $"fnptr_{buildArgs.Config}_{id}" },
id);
Assert.Matches("warning.*Skipping.*because.*function pointer", output);
Assert.Matches("warning.*using_sum_one", output);
Assert.Matches("warning\\sWASM0001.*Could\\snot\\sget\\spinvoke.*Parsing\\sfunction\\spointer\\stypes", output);
Assert.Matches("warning\\sWASM0001.*Skipping.*using_sum_one.*because.*function\\spointer", output);
output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id);
Assert.Contains("Main running", output);
......@@ -108,8 +112,44 @@ public static int Main()
(buildArgs, string output) = BuildForVariadicFunctionTests(code,
buildArgs with { ProjectName = $"fnptr_variadic_{buildArgs.Config}_{id}" },
id);
Assert.Matches("warning.*Skipping.*because.*function pointer", output);
Assert.Matches("warning.*using_sum_one", output);
Assert.Matches("warning\\sWASM0001.*Could\\snot\\sget\\spinvoke.*Parsing\\sfunction\\spointer\\stypes", output);
Assert.Matches("warning\\sWASM0001.*Skipping.*using_sum_one.*because.*function\\spointer", output);
output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id);
Assert.Contains("Main running", output);
}
[Theory]
[BuildAndRun(host: RunHost.Chrome)]
public void DllImportWithFunctionPointers_WarningsAsMessages(BuildArgs buildArgs, RunHost host, string id)
{
string code =
"""
using System;
using System.Runtime.InteropServices;
public class Test
{
public static int Main()
{
Console.WriteLine("Main running");
return 42;
}
[DllImport("someting")]
public unsafe static extern void SomeFunction1(delegate* unmanaged<int> callback);
}
""";
(buildArgs, string output) = BuildForVariadicFunctionTests(
code,
buildArgs with { ProjectName = $"fnptr_{buildArgs.Config}_{id}" },
id,
verbosity: "normal",
extraProperties: "<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessage);WASM0001</MSBuildWarningsAsMessages>"
);
Assert.DoesNotContain("warning WASM0001", output);
output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id);
Assert.Contains("Main running", output);
......@@ -166,12 +206,14 @@ public void BuildNativeInNonEnglishCulture(BuildArgs buildArgs, string culture,
Assert.Contains("square: 25", output);
}
private (BuildArgs, string) BuildForVariadicFunctionTests(string programText, BuildArgs buildArgs, string id)
private (BuildArgs, string) BuildForVariadicFunctionTests(string programText, BuildArgs buildArgs, string id, string? verbosity = null, string extraProperties = "")
{
extraProperties += "<AllowUnsafeBlocks>true</AllowUnsafeBlocks><_WasmDevel>true</_WasmDevel>";
string filename = "variadic.o";
buildArgs = ExpandBuildArgs(buildArgs,
extraItems: $"<NativeFileReference Include=\"{filename}\" />",
extraProperties: "<AllowUnsafeBlocks>true</AllowUnsafeBlocks><_WasmDevel>true</_WasmDevel>");
extraProperties: extraProperties);
(_, string output) = BuildProject(buildArgs,
id: id,
......@@ -183,6 +225,7 @@ public void BuildNativeInNonEnglishCulture(BuildArgs buildArgs, string culture,
Path.Combine(_projectDir!, filename));
},
Publish: buildArgs.AOT,
Verbosity: verbosity,
DotnetWasmFromRuntimePack: false));
return (buildArgs, output);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册