From fe8a61f98aac9ce9f932701e86105c05f3ce7aeb Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 9 Sep 2024 22:31:43 -0500 Subject: [PATCH 1/4] Update more generating code --- src/tasks/AotCompilerTask/MonoAOTCompiler.cs | 114 +++++++------- .../AotCompilerTask/MonoAOTCompiler.csproj | 2 + .../JoinedString.cs | 84 ++++++----- .../WasmAppBuilder/InterpToNativeGenerator.cs | 141 ++++++++---------- .../WasmAppBuilder/PInvokeTableGenerator.cs | 5 +- .../WasmAppBuilder/WasmAppBuilder.csproj | 1 + 6 files changed, 179 insertions(+), 168 deletions(-) rename src/tasks/{WasmAppBuilder => Common}/JoinedString.cs (63%) diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs index 89241ebdd85f46..e6dfe75f3a8a05 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.cs +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.cs @@ -16,6 +16,8 @@ using Microsoft.Build.Utilities; using System.Reflection.PortableExecutable; +using JoinedString; + public class MonoAOTCompiler : Microsoft.Build.Utilities.Task { /// @@ -714,16 +716,12 @@ private PrecompileArguments GetPrecompileArgumentsFor(ITaskItem assemblyItem, st if (DirectPInvokes.Length > 0) { - var directPInvokesSB = new StringBuilder("direct-pinvokes="); - Array.ForEach(DirectPInvokes, directPInvokeItem => directPInvokesSB.Append($"{directPInvokeItem.ItemSpec};")); - aotArgs.Add(directPInvokesSB.ToString()); + aotArgs.Add($$"""direct-pinvokes={{DirectPInvokes.Join("", d => $"{d.ItemSpec};")}}"""); } if (DirectPInvokeLists.Length > 0) { - var directPInvokeListsSB = new StringBuilder("direct-pinvoke-lists="); - Array.ForEach(DirectPInvokeLists, directPInvokeListItem => directPInvokeListsSB.Append($"{directPInvokeListItem.GetMetadata("FullPath")};")); - aotArgs.Add(directPInvokeListsSB.ToString()); + aotArgs.Add($$"""direct-pinvoke-lists={{DirectPInvokeLists.Join("", d => $"{d.GetMetadata("FullPath")};")}}"""); } if (UseDwarfDebug) @@ -1109,62 +1107,66 @@ private bool GenerateAotModulesTable(IEnumerable assemblies, string[] Directory.CreateDirectory(Path.GetDirectoryName(outputFile)!); using TempFileName tmpAotModulesTablePath = new(); - using (var writer = File.CreateText(tmpAotModulesTablePath.Path)) + using (var writer = new JoinedStringStreamWriter(tmpAotModulesTablePath.Path, false)) { if (parsedAotModulesTableLanguage == MonoAotModulesTableLanguage.C) { - writer.WriteLine("#include "); - - foreach (var symbol in symbols) - { - writer.WriteLine($"extern void *{symbol};"); - } - writer.WriteLine("void register_aot_modules (void);"); - writer.WriteLine("void register_aot_modules (void)"); - writer.WriteLine("{"); - foreach (var symbol in symbols) - { - writer.WriteLine($"\tmono_aot_register_module ({symbol});"); - } - writer.WriteLine("}"); - - foreach (var profiler in profilers ?? Enumerable.Empty()) - { - writer.WriteLine($"void mono_profiler_init_{profiler} (const char *desc);"); - writer.WriteLine("EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_" + profiler + " (const char *desc) { mono_profiler_init_" + profiler + " (desc); }"); - } - - if (parsedAotMode == MonoAotMode.LLVMOnly) - { - writer.WriteLine("#define EE_MODE_LLVMONLY 1"); - } - - if (parsedAotMode == MonoAotMode.LLVMOnlyInterp) - { - writer.WriteLine("#define EE_MODE_LLVMONLY_INTERP 1"); - } + profilers ??= Array.Empty(); + writer.Write( + $$""" + #include " + {{symbols.Join(writer.NewLine, s => + $"extern void *{s};") + }} + + void register_aot_modules (void); + void register_aot_modules (void) + { + {{symbols.Join(writer.NewLine, s => + $" mono_aot_register_module ({s});") + }} + } + + {{profilers.Join(writer.NewLine, profiler => + $$$"""" + void mono_profiler_init_{{{profiler}}} (const char *desc); + EMSCRIPTEN_KEEPALIVE void mono_wasm_load_profiler_{{{profiler}}} (const char *desc) + { + mono_profiler_init_{{{profiler}}} (desc); + } + """") + }} + + {{parsedAotMode switch + { + MonoAotMode.LLVMOnly => "#define EE_MODE_LLVMONLY 1", + MonoAotMode.LLVMOnlyInterp => "#define EE_MODE_LLVMONLY_INTERP 1", + _ => "" + } + }} + """); } else if (parsedAotModulesTableLanguage == MonoAotModulesTableLanguage.ObjC) { - writer.WriteLine("#include "); - writer.WriteLine("#include "); - writer.WriteLine(""); - writer.WriteLine("#if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || FORCE_AOT)"); - - foreach (var symbol in symbols) - { - writer.WriteLine($"extern void *{symbol};"); - } - - writer.WriteLine("void register_aot_modules (void);"); - writer.WriteLine("void register_aot_modules (void)"); - writer.WriteLine("{"); - foreach (var symbol in symbols) - { - writer.WriteLine($"\tmono_aot_register_module ({symbol});"); - } - writer.WriteLine("}"); - writer.WriteLine("#endif"); + writer.Write( + $$""" + #include + #include + + #if TARGET_OS_IPHONE && (!TARGET_IPHONE_SIMULATOR || FORCE_AOT) + {{symbols.Join(writer.NewLine, s => + $"extern void *{s};") + }} + + void register_aot_modules (void); + void register_aot_modules (void) + { + {{symbols.Join(writer.NewLine, s => + $" mono_aot_register_module ({s});") + }} + } + #endif + """); } else { diff --git a/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj b/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj index 0afdb5563cc660..288fa81b94c262 100644 --- a/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj +++ b/src/tasks/AotCompilerTask/MonoAOTCompiler.csproj @@ -24,6 +24,8 @@ + + diff --git a/src/tasks/WasmAppBuilder/JoinedString.cs b/src/tasks/Common/JoinedString.cs similarity index 63% rename from src/tasks/WasmAppBuilder/JoinedString.cs rename to src/tasks/Common/JoinedString.cs index 28d411e6522734..fea81cc88f729a 100644 --- a/src/tasks/WasmAppBuilder/JoinedString.cs +++ b/src/tasks/Common/JoinedString.cs @@ -12,12 +12,12 @@ namespace JoinedString; internal static class JoinedStringExtensions { - public static JoinedStringEnumerable Join(this IEnumerable list, string separator) - => JoinedStringEnumerable.Join(list, separator); - public static JoinedStringEnumerable Join(this IEnumerable list, string separator, Func formatter) - => JoinedStringEnumerable.Join(list, separator, formatter); - public static JoinedStringEnumerable Join(this IEnumerable list, string separator, Func formatter) - => JoinedStringEnumerable.Join(list, separator, formatter); + public static ConcatinatedString Join(this IEnumerable list, string separator) + => ConcatinatedString.Join(list, separator); + public static ConcatinatedString Join(this IEnumerable list, string separator, Func formatter) + => ConcatinatedString.Join(list, separator, formatter); + public static ConcatinatedString Join(this IEnumerable list, string separator, Func formatter) + => ConcatinatedString.Join(list, separator, formatter); public static JoinedList Join(this IList list, string separator) => new JoinedList(list, separator, (item, _) => $"{item}"); @@ -27,14 +27,15 @@ public static JoinedList Join(this IList list, string separator, Func new JoinedList(list, separator, formatter); } - -internal sealed record JoinedList(IList items, string separator, Func formatter) +internal sealed record JoinedList(IList items, string separator, Func formatter) : IStringSegments { public IEnumerator GetEnumerator() { + bool hasSeparator = !string.IsNullOrEmpty(separator); + for (int i = 0; i < items.Count; i++) { - if (i != 0) + if (hasSeparator && i != 0) yield return separator; yield return formatter(items[i], i); } @@ -51,30 +52,36 @@ public override string ToString() } } -internal sealed class JoinedStringEnumerable : IEnumerable +internal interface IStringSegments { + public IEnumerator GetEnumerator(); +} + +internal sealed class ConcatinatedString : IStringSegments, IEnumerable { private readonly IEnumerable _values; - private JoinedStringEnumerable(IEnumerable values) + public ConcatinatedString(IEnumerable values) { _values = values; } - public static JoinedStringEnumerable Join(IEnumerable values, string separator) - => new JoinedStringEnumerable(JoinInternal(values, separator, (x, _) => x)); + public static ConcatinatedString Join(IEnumerable values, string separator) + => new ConcatinatedString(JoinInternal(values, separator, (x, _) => x)); - public static JoinedStringEnumerable Join(IEnumerable values, string separator, Func format) - => new JoinedStringEnumerable(JoinInternal(values, separator, (x, _) => format(x))); + public static ConcatinatedString Join(IEnumerable values, string separator, Func format) + => new ConcatinatedString(JoinInternal(values, separator, (x, _) => format(x))); - public static JoinedStringEnumerable Join(IEnumerable values, string separator, Func format) - => new JoinedStringEnumerable(JoinInternal(values, separator, format)); + public static ConcatinatedString Join(IEnumerable values, string separator, Func format) + => new ConcatinatedString(JoinInternal(values, separator, format)); private static IEnumerable JoinInternal(IEnumerable values, string separator, Func format) { int index = 0; + bool hasSeparator = !string.IsNullOrEmpty(separator); + foreach (var value in values) { - if (index != 0) + if (hasSeparator && index != 0) yield return separator; yield return format(value, index++); } @@ -96,11 +103,9 @@ public override string ToString() internal sealed class JoinedStringStreamWriter : StreamWriter { - // since we are intentionally using multi-line string writes, // we want to capture the compile-time new line - private string CompileTimeNewLine = -@" + private string CompileTimeNewLine = @" "; public JoinedStringStreamWriter(Stream stream) : base(stream) @@ -116,25 +121,41 @@ public JoinedStringStreamWriter(string path, bool append) : base(path, append) #if NET8_0_OR_GREATER #pragma warning disable CA1822 // Mark members as static #pragma warning disable IDE0060 // Remove unused parameter - public void Write([InterpolatedStringHandlerArgument("")] JoinedStringWriterHandler builder) + public void Write([InterpolatedStringHandlerArgument("")] StringSegmentStreamWriterHandler builder) { // The builder writes directly to the writer } #pragma warning restore IDE0060 #pragma warning restore CA1822 #endif + + public void Write(IStringSegments list) + { + foreach (var item in list) + { + Write(item); + } + } + + public void WriteLine(IStringSegments list) + { + foreach (var item in list) + { + Write(item); + } + WriteLine(); + } } #if NET8_0_OR_GREATER [InterpolatedStringHandler] -internal ref struct JoinedStringWriterHandler +internal ref struct StringSegmentStreamWriterHandler { private JoinedStringStreamWriter _writer; #pragma warning disable IDE0060 - public JoinedStringWriterHandler(int literalLength, int formattedCount, JoinedStringStreamWriter writer) + public StringSegmentStreamWriterHandler(int literalLength, int formattedCount, JoinedStringStreamWriter writer) { - writer.Flush(); _writer = writer; } #pragma warning restore IDE0060 @@ -145,15 +166,7 @@ public JoinedStringWriterHandler(int literalLength, int formattedCount, JoinedSt public void AppendFormatted(char[] buffer, int index, int count) => _writer.Write(buffer, index, count); public void AppendFormatted(string format, object? arg0, object? arg1, object? arg2) => _writer.Write(format, arg0, arg1, arg2); - public void AppendFormatted(JoinedStringEnumerable list) - { - foreach (var item in list) - { - _writer.Write(item); - } - } - - public void AppendFormatted(JoinedList list) + public void AppendFormatted(IStringSegments list) { foreach (var item in list) { @@ -162,8 +175,7 @@ public void AppendFormatted(JoinedList list) } public override string ToString() - { - _writer.Flush(); + {; return ""; } } diff --git a/src/tasks/WasmAppBuilder/InterpToNativeGenerator.cs b/src/tasks/WasmAppBuilder/InterpToNativeGenerator.cs index 7dfcab267a8431..ad8a6a7df38745 100644 --- a/src/tasks/WasmAppBuilder/InterpToNativeGenerator.cs +++ b/src/tasks/WasmAppBuilder/InterpToNativeGenerator.cs @@ -12,6 +12,7 @@ using System.Diagnostics.CodeAnalysis; using WasmAppBuilder; +using JoinedString; // // This class generates the icall_trampoline_dispatch () function used by the interpreter to call native code on WASM. // It should be kept in sync with mono_wasm_interp_to_native_trampoline () in the runtime. @@ -41,7 +42,22 @@ public void Generate(IEnumerable cookies, string outputPath) private static void Emit(StreamWriter w, IEnumerable cookies) { - w.WriteLine(""" + // Use OrderBy because Order() is not available in net472 + var signatures = cookies.OrderBy(c => c).Distinct().ToArray(); + Array.Sort(signatures, StringComparer.Ordinal); + + + static IEnumerable Args (string signature) + { + for (int i = 1; i < signature.Length; ++i) + yield return signature[i]; + } + + static (bool isVoid, string nativeType) Result (string signature) + => new (SignatureMapper.IsVoidSignature(signature), SignatureMapper.CharToNativeType(signature[0])); + + w.Write( + """ /* * GENERATED FILE, DON'T EDIT * Generated by InterpToNativeGenerator @@ -49,55 +65,37 @@ private static void Emit(StreamWriter w, IEnumerable cookies) #include "pinvoke.h" #include + """); - // Use OrderBy because Order() is not available in net472 - var signatures = cookies.OrderBy(c => c).Distinct().ToArray(); foreach (var signature in signatures) { try { - w.WriteLine("static void"); - w.WriteLine($"wasm_invoke_{signature.ToLower(CultureInfo.InvariantCulture)} (void *target_func, MonoInterpMethodArguments *margs)"); - w.WriteLine("{"); - - w.Write($"\ttypedef {SignatureMapper.CharToNativeType(signature[0])} (*T)("); - for (int i = 1; i < signature.Length; ++i) - { - char p = signature[i]; - if (i > 1) - w.Write(", "); - w.Write($"{SignatureMapper.CharToNativeType(p)} arg_{i - 1}"); - } - - if (signature.Length == 1) - w.Write("void"); - - w.WriteLine(");\n\tT func = (T)target_func;"); - var ctx = new EmitCtx(); - - w.Write("\t"); - if (!SignatureMapper.IsVoidSignature(signature)) - w.Write($"{SignatureMapper.CharToNativeType(signature[0])} res = "); - - w.Write("func ("); - for (int i = 1; i < signature.Length; ++i) - { - char p = signature[i]; - if (i > 1) - w.Write(", "); - w.Write(ctx.Emit(p)); - } - w.WriteLine(");"); - - if (!SignatureMapper.IsVoidSignature(signature)) - { - w.WriteLine($"\tvoid *retval = mono_wasm_interp_method_args_get_retval (margs);"); - w.WriteLine($"\t*({SignatureMapper.CharToNativeType(signature[0])}*)retval = res;"); - } - - w.WriteLine("}\n"); + var result = Result(signature); + var args = Args(signature); + w.Write( + $$""" + + static void + wasm_invoke_{{signature.ToLower(CultureInfo.InvariantCulture)}} (void *target_func, MonoInterpMethodArguments *margs) + { + typedef {{result.nativeType}} (*T)({{args.Join(", ", (p, i) => $"{SignatureMapper.CharToNativeType(p)} arg_{i}")}}{{(signature.Length == 1 ? "void" : "")}}); + T func = (T)target_func; + {{(result.isVoid ? + $$"""" + func ({{args.Join(", ", p => $"{ctx.Emit(p)}")}}); + """" : + $$"""" + {{result.nativeType}} res = func ({{args.Join(", ", p => $"{ctx.Emit(p)}")}}); + + void *retval = mono_wasm_interp_method_args_get_retval (margs); + *({{result.nativeType}} *)retval = res; + """")}} + } + + """); } catch (InvalidSignatureCharException e) { @@ -105,42 +103,35 @@ private static void Emit(StreamWriter w, IEnumerable cookies) } } - Array.Sort(signatures); + w.Write( + $$""" - w.WriteLine("static void* interp_to_native_invokes[] = {"); - foreach (var sig in signatures) - { - var lsig = sig.ToLower(CultureInfo.InvariantCulture); - w.WriteLine($"\twasm_invoke_{lsig},"); - } - w.WriteLine("};"); - - w.WriteLine("static const char* interp_to_native_signatures[] = {"); - - foreach (var signature in signatures) - w.WriteLine($"\t\"{signature}\","); + typedef struct { + const char* signature; + void* func; + } InterpToNative; - w.WriteLine("};"); + static InterpToNative interp_to_native_invokes [] = { + {{signatures.Join($",{w.NewLine}", signature => + $" {{\"{signature}\", wasm_invoke_{signature.ToLower(CultureInfo.InvariantCulture)}}}") + }} + }; - w.WriteLine($"static unsigned int interp_to_native_signatures_count = {signatures.Length};"); - w.WriteLine(); - w.WriteLine(""" - static int - compare_icall_tramp (const void *key, const void *elem) - { - return strcmp (key, *(void**)elem); - } + static int + compare_signature (const void *key, const void *elem) + { + return strcmp (key, ((InterpToNative *)elem)->signature); + } - static void* - mono_wasm_interp_to_native_callback (char* cookie) - { - void* p = bsearch (cookie, interp_to_native_signatures, interp_to_native_signatures_count, sizeof (void*), compare_icall_tramp); - if (!p) - return NULL; - int idx = (const char**)p - (const char**)interp_to_native_signatures; - return interp_to_native_invokes [idx]; - }; - """); + static void* + mono_wasm_interp_to_native_callback (char* cookie) + { + InterpToNative *m2n = bsearch (cookie, interp_to_native_invokes, sizeof(interp_to_native_invokes) / sizeof(InterpToNative), sizeof (InterpToNative), compare_signature); + if (!m2n) + return NULL; + return m2n->func; + }; + """); } private sealed class EmitCtx diff --git a/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs b/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs index bf500b7996b077..a15faea3873384 100644 --- a/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs +++ b/src/tasks/WasmAppBuilder/PInvokeTableGenerator.cs @@ -95,6 +95,7 @@ private void EmitPInvokeTable(StreamWriter w, SortedDictionary m #include #include #include "runtime.h" + #include "pinvoke.h" """); var pinvokesGroupedByEntryPoint = pinvokes @@ -392,7 +393,9 @@ private void EmitNativeToInterp(StreamWriter w, List callbacks) $$""" static UnmanagedExport wasm_native_to_interp_table[] = { - {{callbacks.Join($",{w.NewLine} ", cb => $"{{\"{EscapeLiteral(cb.Key)}\", {cb.Token}, {cb.EntrySymbol}}}")}} + {{callbacks.Join($",{w.NewLine}", cb => + $" {{\"{EscapeLiteral(cb.Key)}\", {cb.Token}, {cb.EntrySymbol}}}" + )}} }; """); diff --git a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj index 34a689f680da40..e1d281d3d1a217 100644 --- a/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj +++ b/src/tasks/WasmAppBuilder/WasmAppBuilder.csproj @@ -20,6 +20,7 @@ + From 0f27d69856a23c2f3d7ba40d578d5a4b67d85ddf Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 10 Sep 2024 09:49:58 -0500 Subject: [PATCH 2/4] Update test for windows console --- .../Wasm.Build.Tests/PInvokeTableGeneratorTests.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index 24715f44740baf..efb4c8b11371f3 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -452,8 +452,8 @@ public unsafe static int Main() { ((delegate* unmanaged)&A.Conflict.C)(); ((delegate* unmanaged)&B.Conflict.C)(); - ((delegate* unmanaged)&A.Conflict.C\u733f)(); - ((delegate* unmanaged)&B.Conflict.C\u733f)(); + ((delegate* unmanaged)&A.Conflict.C_\u733f)(); + ((delegate* unmanaged)&B.Conflict.C_\u733f)(); return 42; } } @@ -498,8 +498,14 @@ public static void C() { output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); Assert.Contains("A.Conflict.C", output); Assert.Contains("B.Conflict.C", output); - Assert.Contains("A.Conflict.C\U0001F412", output); - Assert.Contains("B.Conflict.C\U0001F412", output); + if (OperationSystem.IsWindows()) { + // Windows console unicode support is not great + Assert.Contains("A.Conflict.C_", output); + Assert.Contains("B.Conflict.C_", output); + } else { + Assert.Contains("A.Conflict.C_\U0001F412", output); + Assert.Contains("B.Conflict.C_\U0001F412", output); + } } [Theory] From 18c8f1dd74833283bdc7db322acbfe7e9b06a4aa Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 10 Sep 2024 10:28:46 -0500 Subject: [PATCH 3/4] Fix typo --- src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index efb4c8b11371f3..04c884aed5e5b2 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -498,7 +498,7 @@ public static void C() { output = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); Assert.Contains("A.Conflict.C", output); Assert.Contains("B.Conflict.C", output); - if (OperationSystem.IsWindows()) { + if (OperatingSystem.IsWindows()) { // Windows console unicode support is not great Assert.Contains("A.Conflict.C_", output); Assert.Contains("B.Conflict.C_", output); From e448e12347a81a1bd9b3096efbb8b5d6377ca39e Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Tue, 10 Sep 2024 11:05:51 -0500 Subject: [PATCH 4/4] Fix logico --- .../wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index 04c884aed5e5b2..0c99d38835e2c8 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -452,8 +452,8 @@ public unsafe static int Main() { ((delegate* unmanaged)&A.Conflict.C)(); ((delegate* unmanaged)&B.Conflict.C)(); - ((delegate* unmanaged)&A.Conflict.C_\u733f)(); - ((delegate* unmanaged)&B.Conflict.C_\u733f)(); + ((delegate* unmanaged)&A.Conflict.C\u733f)(); + ((delegate* unmanaged)&B.Conflict.C\u733f)(); return 42; } } @@ -467,7 +467,7 @@ public static void C() { [UnmanagedCallersOnly(EntryPoint = "A_Conflict_C\u733f")] public static void C\u733f() { - Console.WriteLine("A.Conflict.C\U0001F412"); + Console.WriteLine("A.Conflict.C_\U0001F412"); } } } @@ -481,7 +481,7 @@ public static void C() { [UnmanagedCallersOnly(EntryPoint = "B_Conflict_C\u733f")] public static void C\u733f() { - Console.WriteLine("B.Conflict.C\U0001F412"); + Console.WriteLine("B.Conflict.C_\U0001F412"); } } }