From 353744bb07cdd5436ab0e06cbb7116db32cbad76 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Tue, 28 May 2024 23:03:35 -0400 Subject: [PATCH 01/14] fix(macOS): Don't link icalls to avoid using the cross-compiler --- .vsts-ci-macos.yml | 13 ++++++++----- src/Uno.Wasm.Bootstrap/ShellTask.cs | 10 +++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.vsts-ci-macos.yml b/.vsts-ci-macos.yml index 66010f3b4..d834ca93d 100644 --- a/.vsts-ci-macos.yml +++ b/.vsts-ci-macos.yml @@ -23,11 +23,7 @@ jobs: version: 8.0.100 includePreviewVersions: true - - bash: | - cd $(Agent.WorkFolder) - wget https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip - unzip ninja-mac.zip -d ninja-mac - + - bash: brew install ninja displayName: 'Install Ninja' # - bash: | @@ -56,6 +52,13 @@ jobs: dotnet build -m:1 /bl:$(build.artifactstagingdirectory)/SampleNet6-mac.binlog displayName: Build NetCore-Wasm Sample + # Static linking test (net5) without the linker + - pwsh: | + cd $(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Interpreter + dotnet clean -c Release /p:DISABLE_CLIHOST_NET6=true + dotnet publish -c Release /m:1 /p:DISABLE_CLIHOST_NET6=true /p:WasmShellEmccLinkOptimization=false /p:WasmShellILLinkerEnabled=false /bl:$(build.artifactstagingdirectory)/SampleNet5-nolinker-macos.binlog + displayName: Build StaticLinking.Interpreter Sample (net5 without linker) + - task: PublishBuildArtifacts@1 condition: always() inputs: diff --git a/src/Uno.Wasm.Bootstrap/ShellTask.cs b/src/Uno.Wasm.Bootstrap/ShellTask.cs index d8a87b27e..b7807b2a3 100644 --- a/src/Uno.Wasm.Bootstrap/ShellTask.cs +++ b/src/Uno.Wasm.Bootstrap/ShellTask.cs @@ -810,7 +810,15 @@ private void RunPackager() + (EnableSimd ? "-simd" : "") + " " + (EnableJiterpreter ? "-jiterpreter" : "") + " " + (PrintAOTSkippedMethods ? "-print-skipped-aot-methods" : "") + " " - + (string.IsNullOrWhiteSpace(RuntimeOptions) ? "" : $"--runtime-options \"{RuntimeOptions}\" "); + + (string.IsNullOrWhiteSpace(RuntimeOptions) ? "" : $"--runtime-options \"{RuntimeOptions}\" ") + + // Disable icalls generation on macOS, as it's using the cross-compiler that is not available + + (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "--no-link-icalls" : ""); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && IsRuntimeAOT()) + { + throw new Exception("Building with AOT is not supported on macOS"); + } var pthreadPoolSizeParam = $"--pthread-pool-size={PThreadsPoolSize}"; From 0badff732d8c9c96f9e7958097f638c0a9767b2b Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Tue, 28 May 2024 23:19:36 -0400 Subject: [PATCH 02/14] chore: Adjust icall building for pinvoke --- src/Uno.Wasm.Packager/packager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Uno.Wasm.Packager/packager.cs b/src/Uno.Wasm.Packager/packager.cs index cd1229a1c..651a584c0 100644 --- a/src/Uno.Wasm.Packager/packager.cs +++ b/src/Uno.Wasm.Packager/packager.cs @@ -1862,7 +1862,9 @@ int Run (string[] args) { pinvoke_assemblies += $"{a.linkout_path} "; ninja.WriteLine ($"build $builddir/pinvoke-table.h: cpifdiff $builddir/pinvoke-table.h.tmp"); - ninja.WriteLine ($"build $builddir/pinvoke-table.h.tmp: gen-pinvoke-table $builddir/icall-table.json {pinvoke_assemblies}"); + + var icallTable = link_icalls ? "$builddir/icall-table.json" : ""; + ninja.WriteLine ($"build $builddir/pinvoke-table.h.tmp: gen-pinvoke-table {icallTable} {pinvoke_assemblies}"); if (is_netcore) { From 74309dc5fbeb11fb3417bfe2db40d2e858e43605 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 08:47:34 -0400 Subject: [PATCH 03/14] chore: Use static table --- src/Uno.Wasm.Packager/packager.cs | 2 +- .../IcallTableGenerator.net5.cs | 52 ++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/Uno.Wasm.Packager/packager.cs b/src/Uno.Wasm.Packager/packager.cs index 651a584c0..8fb4a4d22 100644 --- a/src/Uno.Wasm.Packager/packager.cs +++ b/src/Uno.Wasm.Packager/packager.cs @@ -1863,7 +1863,7 @@ int Run (string[] args) { ninja.WriteLine ($"build $builddir/pinvoke-table.h: cpifdiff $builddir/pinvoke-table.h.tmp"); - var icallTable = link_icalls ? "$builddir/icall-table.json" : ""; + var icallTable = link_icalls ? "$builddir/icall-table.json" : "__static_icalls__"; ninja.WriteLine ($"build $builddir/pinvoke-table.h.tmp: gen-pinvoke-table {icallTable} {pinvoke_assemblies}"); if (is_netcore) diff --git a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs index 785a33863..f5c1e4c85 100644 --- a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs +++ b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs @@ -33,6 +33,38 @@ internal sealed class IcallTableGenerator private TaskLoggingHelper Log { get; set; } private readonly Func _fixupSymbolName; + /// + /// This table is an extract of net8's icalls table, in order to avoid + /// having to compute it on macOS, which cannot run mono-aot-cross on that platform. + /// + string[] _staticSignatures = new[] { + "III", + "IIIIIIIII", + "IIIIIIIIII", + "IIIIIII", + "IIIIII", + "IIII", + "VIIIIIII", + "VIIIIIIII", + "VIIIII", + "II", + "VIII", + "VII", + "VIIII", + "IIIII", + "I", + "VIIL", + "L", + "VI", + "VIIIIII", + "DD", + "DDD", + "DDI", + "LILL", + "LIL", + "V" + }; + // // Given the runtime generated icall table, and a set of assemblies, generate // a smaller linked icall table mapping tokens to C function names @@ -43,8 +75,15 @@ public IcallTableGenerator(string? runtimeIcallTableFile, Func f { Log = log; _fixupSymbolName = fixupSymbolName; - if (runtimeIcallTableFile != null) + if (runtimeIcallTableFile != null && !runtimeIcallTableFile.Equals("__static_icalls__")) ReadTable(runtimeIcallTableFile); + else + { + foreach (var sig in _staticSignatures) + { + _signatures.Add(sig); + } + } } public void ScanAssembly(Assembly asm) @@ -74,6 +113,17 @@ public IEnumerable Generate(string? outputPath) } } + Log.LogMessage(MessageImportance.Low, $"Icalls signatures: " + string.Join(",", _signatures)); + + // validate that the _signatures are in the _staticSignatures table + foreach (var sig in _signatures) + { + if (!_staticSignatures.Contains(sig)) + { + throw new Exception("Icall signature '{sig}' is not in the static icall signatures table"); + } + } + return _signatures; } From 875ceb8075609dc58ab77254058310e88a09e4e3 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 09:09:10 -0400 Subject: [PATCH 04/14] chore: Adjust tuner static generation --- src/Uno.Wasm.Packager/packager.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Uno.Wasm.Packager/packager.cs b/src/Uno.Wasm.Packager/packager.cs index 8fb4a4d22..643f05bc3 100644 --- a/src/Uno.Wasm.Packager/packager.cs +++ b/src/Uno.Wasm.Packager/packager.cs @@ -1856,6 +1856,11 @@ int Run (string[] args) { ninja.WriteLine ($"build $builddir/icall-table.h: gen-icall-table {icall_assemblies}"); ninja.WriteLine ($" runtime_table=$builddir/icall-table.json"); } + else + { + // Fake a command so that __static_icalls__ gets to the tuner + ninja.WriteLine ("build __static_icalls__: mkdir"); + } if (gen_pinvoke) { string pinvoke_assemblies = ""; foreach (var a in assemblies.Where(a => a.culture is null)) From a0c8946ca2f00bbb01cf34a26524bd03a64769e2 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 09:41:01 -0400 Subject: [PATCH 05/14] chore: Adjust icalls generation --- src/Uno.Wasm.Packager/packager.cs | 5 +++-- src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Uno.Wasm.Packager/packager.cs b/src/Uno.Wasm.Packager/packager.cs index 643f05bc3..2ada57482 100644 --- a/src/Uno.Wasm.Packager/packager.cs +++ b/src/Uno.Wasm.Packager/packager.cs @@ -1845,9 +1845,10 @@ int Run (string[] args) { ofiles += $" {a.o_path}"; } - ninja.WriteLine ("build $builddir/icall-table.json: gen-runtime-icall-table"); if (link_icalls) { + ninja.WriteLine ("build $builddir/icall-table.json: gen-runtime-icall-table"); + string icall_assemblies = ""; foreach (var a in assemblies.Where(a => a.culture is null)) { if (a.name == "mscorlib" || a.name == "System") @@ -1868,7 +1869,7 @@ int Run (string[] args) { ninja.WriteLine ($"build $builddir/pinvoke-table.h: cpifdiff $builddir/pinvoke-table.h.tmp"); - var icallTable = link_icalls ? "$builddir/icall-table.json" : "__static_icalls__"; + var icallTable = "__static_icalls__"; // RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__static_icalls__" : "$builddir/icall-table.json"; ninja.WriteLine ($"build $builddir/pinvoke-table.h.tmp: gen-pinvoke-table {icallTable} {pinvoke_assemblies}"); if (is_netcore) diff --git a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs index f5c1e4c85..425566776 100644 --- a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs +++ b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs @@ -79,6 +79,8 @@ public IcallTableGenerator(string? runtimeIcallTableFile, Func f ReadTable(runtimeIcallTableFile); else { + Log.LogMessage(MessageImportance.Low, $"Using static signatures"); + foreach (var sig in _staticSignatures) { _signatures.Add(sig); @@ -120,7 +122,7 @@ public IEnumerable Generate(string? outputPath) { if (!_staticSignatures.Contains(sig)) { - throw new Exception("Icall signature '{sig}' is not in the static icall signatures table"); + throw new Exception($"Icall signature '{sig}' is not in the static icall signatures table"); } } From 2efc563a4fab25e7c4c3d12d4662e1839cf1b0fa Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 10:07:06 -0400 Subject: [PATCH 06/14] chore: Adjust signatures static list --- src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs index 425566776..8d56fcd78 100644 --- a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs +++ b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs @@ -62,6 +62,7 @@ internal sealed class IcallTableGenerator "DDI", "LILL", "LIL", + "VL", "V" }; From c5435cbfdd3c7cbea5f55b26a06558b4ec9ad3f3 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 10:13:25 -0400 Subject: [PATCH 07/14] chore: Adjust signatures validations --- .../IcallTableGenerator.net5.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs index 8d56fcd78..072a1b9c1 100644 --- a/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs +++ b/src/Uno.Wasm.Tuner/IcallTableGenerator.net5.cs @@ -77,7 +77,18 @@ public IcallTableGenerator(string? runtimeIcallTableFile, Func f Log = log; _fixupSymbolName = fixupSymbolName; if (runtimeIcallTableFile != null && !runtimeIcallTableFile.Equals("__static_icalls__")) + { ReadTable(runtimeIcallTableFile); + + // validate that the _signatures are in the _staticSignatures table + foreach (var sig in _signatures) + { + if (!_staticSignatures.Contains(sig)) + { + throw new Exception($"Icall signature '{sig}' is not in the static icall signatures table"); + } + } + } else { Log.LogMessage(MessageImportance.Low, $"Using static signatures"); @@ -118,15 +129,6 @@ public IEnumerable Generate(string? outputPath) Log.LogMessage(MessageImportance.Low, $"Icalls signatures: " + string.Join(",", _signatures)); - // validate that the _signatures are in the _staticSignatures table - foreach (var sig in _signatures) - { - if (!_staticSignatures.Contains(sig)) - { - throw new Exception($"Icall signature '{sig}' is not in the static icall signatures table"); - } - } - return _signatures; } From a9d093da7e5c9369d9b6fc03f05161f1ded46757 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 10:27:46 -0400 Subject: [PATCH 08/14] chore: Add macos validation --- .vsts-ci-macos.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.vsts-ci-macos.yml b/.vsts-ci-macos.yml index d834ca93d..0e2a82063 100644 --- a/.vsts-ci-macos.yml +++ b/.vsts-ci-macos.yml @@ -59,6 +59,14 @@ jobs: dotnet publish -c Release /m:1 /p:DISABLE_CLIHOST_NET6=true /p:WasmShellEmccLinkOptimization=false /p:WasmShellILLinkerEnabled=false /bl:$(build.artifactstagingdirectory)/SampleNet5-nolinker-macos.binlog displayName: Build StaticLinking.Interpreter Sample (net5 without linker) + - pwsh: | + $(build.sourcesdirectory)/build/scripts/run-tests.sh \ + "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Interpreter/bin/Release/net5.0/dist" \ + "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Aot.UITests" "http://localhost:8000/" + displayName: StaticLinking Interpreter + env: + BUILD_SOURCESDIRECTORY: "$(build.sourcesdirectory)" + - task: PublishBuildArtifacts@1 condition: always() inputs: From 11763d326e6b57e114bec0d2ccc0599c8c5eefb5 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 10:35:43 -0400 Subject: [PATCH 09/14] chore: Adjust testing --- .vsts-ci-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vsts-ci-macos.yml b/.vsts-ci-macos.yml index 0e2a82063..28d418cc7 100644 --- a/.vsts-ci-macos.yml +++ b/.vsts-ci-macos.yml @@ -59,7 +59,7 @@ jobs: dotnet publish -c Release /m:1 /p:DISABLE_CLIHOST_NET6=true /p:WasmShellEmccLinkOptimization=false /p:WasmShellILLinkerEnabled=false /bl:$(build.artifactstagingdirectory)/SampleNet5-nolinker-macos.binlog displayName: Build StaticLinking.Interpreter Sample (net5 without linker) - - pwsh: | + - bash: | $(build.sourcesdirectory)/build/scripts/run-tests.sh \ "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Interpreter/bin/Release/net5.0/dist" \ "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Aot.UITests" "http://localhost:8000/" From 536fee80c970b9afd109448436488ae7373a1161 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 10:57:50 -0400 Subject: [PATCH 10/14] chore: Adjust test for macOS --- src/Uno.Wasm.StaticLinking.Aot.UITests/app.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Uno.Wasm.StaticLinking.Aot.UITests/app.ts b/src/Uno.Wasm.StaticLinking.Aot.UITests/app.ts index 3c4a49e8b..9ed9f5180 100644 --- a/src/Uno.Wasm.StaticLinking.Aot.UITests/app.ts +++ b/src/Uno.Wasm.StaticLinking.Aot.UITests/app.ts @@ -42,7 +42,8 @@ const path = require("path"); console.log(`Results: ${value}`); } - const expected = "InterpreterAndAOT;42;42.30;42.7;e42;True;true;True;1.2;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;gl:true;functionsExportsAvailable:true;sat:True;"; + let expected = process.platform === 'darwin' ? "Interpreter;" : "InterpreterAndAOT;"; + expected += "42;42.30;42.7;e42;True;true;True;1.2;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;gl:true;functionsExportsAvailable:true;sat:True;"; if (value !== expected) { console.log(`Invalid results got ${value}, expected ${expected}`); From 6f538010e909f006b3a3828340286ff2897b433f Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 11:02:16 -0400 Subject: [PATCH 11/14] chore: Adjust ui test --- src/Uno.Wasm.StaticLinking.Aot.UITests/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Uno.Wasm.StaticLinking.Aot.UITests/app.js b/src/Uno.Wasm.StaticLinking.Aot.UITests/app.js index 91fcb72f0..ee3b5f300 100644 --- a/src/Uno.Wasm.StaticLinking.Aot.UITests/app.js +++ b/src/Uno.Wasm.StaticLinking.Aot.UITests/app.js @@ -43,7 +43,8 @@ const path = require("path"); else { console.log(`Results: ${value}`); } - const expected = "InterpreterAndAOT;42;42.30;42.7;e42;True;true;True;1.2;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;gl:true;functionsExportsAvailable:true;sat:True;"; + let expected = process.platform === 'darwin' ? "Interpreter;" : "InterpreterAndAOT;"; + expected += "42;42.30;42.7;e42;True;true;True;1.2;1.4;3.1;0;42;requireJs:true;jsInterop:Invoked;gl:true;functionsExportsAvailable:true;sat:True;"; if (value !== expected) { console.log(`Invalid results got ${value}, expected ${expected}`); process.exit(1); From 11632fa7e81a5886c14543be7c5acee5743d8b5f Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 11:09:06 -0400 Subject: [PATCH 12/14] chore: Adjust test --- .vsts-ci-macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vsts-ci-macos.yml b/.vsts-ci-macos.yml index 28d418cc7..b3a485cf4 100644 --- a/.vsts-ci-macos.yml +++ b/.vsts-ci-macos.yml @@ -63,7 +63,7 @@ jobs: $(build.sourcesdirectory)/build/scripts/run-tests.sh \ "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Interpreter/bin/Release/net5.0/dist" \ "$(build.sourcesdirectory)/src/Uno.Wasm.StaticLinking.Aot.UITests" "http://localhost:8000/" - displayName: StaticLinking Interpreter + displayName: StaticLinking Interpreter Test env: BUILD_SOURCESDIRECTORY: "$(build.sourcesdirectory)" From d7097355f90fbc6dd098da4f74f05136d6024609 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 11:10:05 -0400 Subject: [PATCH 13/14] chore: Adjust packager --- src/Uno.Wasm.Packager/packager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Uno.Wasm.Packager/packager.cs b/src/Uno.Wasm.Packager/packager.cs index 2ada57482..080da28c1 100644 --- a/src/Uno.Wasm.Packager/packager.cs +++ b/src/Uno.Wasm.Packager/packager.cs @@ -6,6 +6,7 @@ using Mono.Options; using Mono.Cecil.Cil; using System.Diagnostics; +using System.Runtime.InteropServices; // // Google V8 style options: @@ -1869,7 +1870,7 @@ int Run (string[] args) { ninja.WriteLine ($"build $builddir/pinvoke-table.h: cpifdiff $builddir/pinvoke-table.h.tmp"); - var icallTable = "__static_icalls__"; // RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__static_icalls__" : "$builddir/icall-table.json"; + var icallTable = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "__static_icalls__" : "$builddir/icall-table.json"; ninja.WriteLine ($"build $builddir/pinvoke-table.h.tmp: gen-pinvoke-table {icallTable} {pinvoke_assemblies}"); if (is_netcore) From e9f7355a6748c46a3fced6e5803d9f48bbb76110 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 29 May 2024 11:41:44 -0400 Subject: [PATCH 14/14] chore: Adjust icall for macos --- src/Uno.Wasm.Packager/packager.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Uno.Wasm.Packager/packager.cs b/src/Uno.Wasm.Packager/packager.cs index 080da28c1..26a61ffb8 100644 --- a/src/Uno.Wasm.Packager/packager.cs +++ b/src/Uno.Wasm.Packager/packager.cs @@ -1846,9 +1846,12 @@ int Run (string[] args) { ofiles += $" {a.o_path}"; } + if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + ninja.WriteLine("build $builddir/icall-table.json: gen-runtime-icall-table"); + } if (link_icalls) { - ninja.WriteLine ("build $builddir/icall-table.json: gen-runtime-icall-table"); string icall_assemblies = ""; foreach (var a in assemblies.Where(a => a.culture is null)) {