diff --git a/src/tasks/WasmAppBuilder/IcallTableGenerator.cs b/src/tasks/WasmAppBuilder/IcallTableGenerator.cs index a1620338bcbe7a10a5c5fe234da27fcdca48aaa1..01d7d0eb4479e39a188cf04fa474c184b52ad34b 100644 --- a/src/tasks/WasmAppBuilder/IcallTableGenerator.cs +++ b/src/tasks/WasmAppBuilder/IcallTableGenerator.cs @@ -245,6 +245,10 @@ private void AppendType(StringBuilder sb, Type t) AppendType(sb, t.GetElementType()!); sb.Append('*'); } + else if (t.IsEnum) + { + AppendType(sb, Enum.GetUnderlyingType(t)); + } else { sb.Append(t.Name switch diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs index 16c9e2e7fd0ac5e56f595c33fb3c55bc0ab8e365..c119db17c282cf53f7f3d3bad7f9d47f359f0bd9 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildEnvironment.cs @@ -15,6 +15,7 @@ public class BuildEnvironment { public string DotNet { get; init; } public string RuntimePackDir { get; init; } + public string WorkloadPacksVersion { get; init; } public bool IsWorkload { get; init; } public string DefaultBuildArgs { get; init; } public IDictionary EnvVars { get; init; } @@ -23,6 +24,8 @@ public class BuildEnvironment public string RuntimeNativeDir { get; init; } public string LogRootPath { get; init; } + public string WorkloadPacksDir { get; init; } + public static readonly string RelativeTestAssetsPath = @"..\testassets\"; public static readonly string TestAssetsPath = Path.Combine(AppContext.BaseDirectory, "testassets"); public static readonly string TestDataPath = Path.Combine(AppContext.BaseDirectory, "data"); @@ -57,6 +60,9 @@ public BuildEnvironment() if (!Directory.Exists(sdkForWorkloadPath)) throw new Exception($"Could not find SDK_FOR_WORKLOAD_TESTING_PATH={sdkForWorkloadPath}"); + if (!Path.IsPathRooted(sdkForWorkloadPath)) + sdkForWorkloadPath = Path.GetFullPath(sdkForWorkloadPath); + EnvVars = new Dictionary(); bool workloadInstalled = EnvironmentVariables.SdkHasWorkloadInstalled != null && EnvironmentVariables.SdkHasWorkloadInstalled == "true"; if (workloadInstalled) @@ -65,7 +71,10 @@ public BuildEnvironment() if (string.IsNullOrEmpty(workloadPacksVersion)) throw new Exception($"Cannot test with workloads without WORKLOAD_PACKS_VER environment variable being set"); - RuntimePackDir = Path.Combine(sdkForWorkloadPath, "packs", "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", workloadPacksVersion); + WorkloadPacksDir = Path.Combine(sdkForWorkloadPath, "packs"); + WorkloadPacksVersion = workloadPacksVersion; + + RuntimePackDir = Path.Combine(WorkloadPacksDir, "Microsoft.NETCore.App.Runtime.Mono.browser-wasm", WorkloadPacksVersion); DirectoryBuildPropsContents = s_directoryBuildPropsForWorkloads; DirectoryBuildTargetsContents = s_directoryBuildTargetsForWorkloads; @@ -78,6 +87,8 @@ public BuildEnvironment() } else { + WorkloadPacksDir = "/dont-use-this-no-workload-installed"; + WorkloadPacksVersion = "dont-use-this-no-workload-installed"; RuntimePackDir = "/dont-check-runtime-pack-dir-for-no-workloads-case"; var appRefDir = EnvironmentVariables.AppRefDir; if (string.IsNullOrEmpty(appRefDir)) diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs index dfb2d35d1be87bfbc900b94393d11c8ce9ea6372..e05792c96788ead39df029e81935d8ef6dbc47c8 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs @@ -359,7 +359,7 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp _testOutput.WriteLine($"Binlog path: {logFilePath}"); _testOutput.WriteLine($"Binlog path: {logFilePath}"); sb.Append($" /bl:\"{logFilePath}\" /nologo"); - sb.Append($" /fl /flp:\"v:diag,LogFile={logFilePath}.log\" /v:{options.Verbosity ?? "minimal"}"); + sb.Append($" /v:{options.Verbosity ?? "minimal"}"); if (buildArgs.ExtraBuildArgs != null) sb.Append($" {buildArgs.ExtraBuildArgs} "); @@ -381,7 +381,7 @@ protected static BuildArgs ExpandBuildArgs(BuildArgs buildArgs, string extraProp // check that we are using the correct runtime pack! - if (options.ExpectSuccess) + if (options.ExpectSuccess && options.AssertAppBundle) { string bundleDir = Path.Combine(GetBinDir(config: buildArgs.Config, targetFramework: options.TargetFramework ?? DefaultTargetFramework), "AppBundle"); AssertBasicAppBundle(bundleDir, buildArgs.ProjectName, buildArgs.Config, options.MainJS ?? "test-main.js", options.HasV8Script, options.HasIcudt, options.DotnetWasmFromRuntimePack ?? !buildArgs.AOT); @@ -938,6 +938,7 @@ public record BuildProjectOptions bool HasIcudt = true, bool UseCache = true, bool ExpectSuccess = true, + bool AssertAppBundle = true, bool CreateProject = true, bool Publish = true, bool BuildOnlyAfterPublish = true, diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index 791c211dfdf111eb9d9a00d7b1301e749d717884..616b0ecc1c32c6d2fbe4e1011eb2919151853606 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; -using System.Reflection; using Xunit; using Xunit.Abstractions; @@ -155,6 +154,120 @@ public static int Main() Assert.Contains("Main running", output); } + [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [BuildAndRun(host: RunHost.None)] + public void IcallWithOverloadedParametersAndEnum(BuildArgs buildArgs, string id) + { + // Build a library containing icalls with overloaded parameters. + + string code = + """ + using System; + using System.Runtime.CompilerServices; + + public static class Interop + { + public enum Numbers { A, B, C, D } + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern void Square(Numbers x); + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern void Square(Numbers x, Numbers y); + + public static void Main() + { + // Noop + } + } + """; + + var libraryBuildArgs = ExpandBuildArgs( + buildArgs with { ProjectName = $"icall_enum_library_{buildArgs.Config}_{id}" } + ); + + (string libraryDir, string output) = BuildProject( + libraryBuildArgs, + id: id + "library", + new BuildProjectOptions( + InitProject: () => + { + File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), code); + }, + Publish: false, + DotnetWasmFromRuntimePack: false, + AssertAppBundle: false + ) + ); + + // Build a project with ManagedToNativeGenerator task reading icalls from the above library and runtime-icall-table.h bellow. + + string projectCode = + """ + + + + + pinvoke-table.h + wasm_m2n_invoke.g.h + runtime-icall-table.h + + + + + ###WasmPInvokeModule### + + + + + + + + """; + + string AddAssembly(string name) => $""; + + string icallTable = + """ + [ + { "klass":"Interop", "icalls": [{} ,{ "name": "Square(Numbers)", "func": "ves_abc", "handles": false } + ,{ "name": "Add(Numbers,Numbers)", "func": "ves_def", "handles": false } + ]} + ] + + """; + + projectCode = projectCode + .Replace("###WasmPInvokeModule###", AddAssembly("System.Private.CoreLib") + AddAssembly("System.Runtime") + AddAssembly(libraryBuildArgs.ProjectName)) + .Replace("###WasmAppBuilder###", Path.Combine(s_buildEnv.WorkloadPacksDir, "Microsoft.NET.Runtime.WebAssembly.Sdk", s_buildEnv.WorkloadPacksVersion, "tasks", DefaultTargetFramework, "WasmAppBuilder.dll")); + + buildArgs = buildArgs with { ProjectName = $"icall_enum_{buildArgs.Config}_{id}", ProjectFileContents = projectCode }; + + _projectDir = null; + + (_, output) = BuildProject( + buildArgs, + id: id + "tasks", + new BuildProjectOptions( + InitProject: () => + { + File.WriteAllText(Path.Combine(_projectDir!, "runtime-icall-table.h"), icallTable); + }, + Publish: buildArgs.AOT, + DotnetWasmFromRuntimePack: false, + UseCache: false, + AssertAppBundle: false + ) + ); + + Assert.DoesNotMatch(".*warning.*Numbers", output); + } + [Theory] [BuildAndRun(host: RunHost.Chrome, parameters: new object[] { "tr_TR.UTF-8" })] public void BuildNativeInNonEnglishCulture(BuildArgs buildArgs, string culture, RunHost host, string id)