-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[wasm] PInvokeTableGenerator: Fixup symbol names with invalid chars #60814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1cfeab3
68192c0
45c60ae
10dca6c
582d3b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,7 @@ public class PInvokeTableGenerator : Task | |
| [Output] | ||
| public string FileWrites { get; private set; } = string.Empty; | ||
|
|
||
| private static char[] s_charsToReplace = new[] { '.', '-', }; | ||
| private static char[] s_charsToReplace = new[] { '.', '-', ',', '|', '<', '>' }; | ||
|
|
||
| public override bool Execute() | ||
| { | ||
|
|
@@ -157,7 +157,7 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary<string, string> modules | |
|
|
||
| foreach (var module in modules.Keys) | ||
| { | ||
| string symbol = ModuleNameToId(module) + "_imports"; | ||
| string symbol = FixupSymbolName(module) + "_imports"; | ||
| w.WriteLine("static PinvokeImport " + symbol + " [] = {"); | ||
|
|
||
| var assemblies_pinvokes = pinvokes. | ||
|
|
@@ -176,7 +176,7 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary<string, string> modules | |
| w.Write("static void *pinvoke_tables[] = { "); | ||
| foreach (var module in modules.Keys) | ||
| { | ||
| string symbol = ModuleNameToId(module) + "_imports"; | ||
| string symbol = FixupSymbolName(module) + "_imports"; | ||
| w.Write(symbol + ","); | ||
| } | ||
| w.WriteLine("};"); | ||
|
|
@@ -187,18 +187,6 @@ private void EmitPInvokeTable(StreamWriter w, Dictionary<string, string> modules | |
| } | ||
| w.WriteLine("};"); | ||
|
|
||
| static string ModuleNameToId(string name) | ||
| { | ||
| if (name.IndexOfAny(s_charsToReplace) < 0) | ||
| return name; | ||
|
|
||
| string fixedName = name; | ||
| foreach (char c in s_charsToReplace) | ||
| fixedName = fixedName.Replace(c, '_'); | ||
|
|
||
| return fixedName; | ||
| } | ||
|
|
||
| static bool ShouldTreatAsVariadic(PInvoke[] candidates) | ||
| { | ||
| if (candidates.Length < 2) | ||
|
|
@@ -216,6 +204,26 @@ static bool ShouldTreatAsVariadic(PInvoke[] candidates) | |
| } | ||
| } | ||
|
|
||
| private static string FixupSymbolName(string name) | ||
| { | ||
| if (name.IndexOfAny(s_charsToReplace) < 0) | ||
| return name; | ||
|
|
||
| string fixedName = name; | ||
| foreach (char c in s_charsToReplace) | ||
| fixedName = fixedName.Replace(c, '_'); | ||
|
|
||
| return fixedName; | ||
| } | ||
|
|
||
| private static string SymbolNameForMethod(MethodInfo method) | ||
| { | ||
| string module_symbol = method.DeclaringType!.Module!.Assembly!.GetName()!.Name!; | ||
| string class_name = method.DeclaringType.Name; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we check |
||
| string method_name = method.Name; | ||
| return FixupSymbolName($"{module_symbol}_{class_name}_{method_name}"); | ||
| } | ||
|
|
||
| private string MapType (Type t) | ||
| { | ||
| string name = t.Name; | ||
|
|
@@ -343,15 +351,12 @@ private void EmitNativeToInterp(StreamWriter w, List<PInvokeCallback> callbacks) | |
|
|
||
| bool is_void = method.ReturnType.Name == "Void"; | ||
|
|
||
| string module_symbol = method.DeclaringType!.Module!.Assembly!.GetName()!.Name!.Replace(".", "_"); | ||
| uint token = (uint)method.MetadataToken; | ||
| string class_name = method.DeclaringType.Name; | ||
| string method_name = method.Name; | ||
| string entry_name = $"wasm_native_to_interp_{module_symbol}_{class_name}_{method_name}"; | ||
| string entry_name = $"wasm_native_to_interp_{SymbolNameForMethod(method)}"; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're compiling for |
||
| if (callbackNames.Contains (entry_name)) | ||
| { | ||
| Error($"Two callbacks with the same name '{method_name}' are not supported."); | ||
| Error($"Two callbacks with the same name '{entry_name}' are not supported."); | ||
| } | ||
|
|
||
| callbackNames.Add (entry_name); | ||
| cb.EntryName = entry_name; | ||
| sb.Append(MapType(method.ReturnType)); | ||
|
|
@@ -395,21 +400,16 @@ private void EmitNativeToInterp(StreamWriter w, List<PInvokeCallback> callbacks) | |
| // Array of function pointers | ||
| w.Write ("static void *wasm_native_to_interp_funcs[] = { "); | ||
| foreach (var cb in callbacks) { | ||
| w.Write (cb.EntryName + ","); | ||
| w.Write ($"\t{cb.EntryName},{Environment.NewLine}"); | ||
| } | ||
| w.WriteLine ("};"); | ||
|
|
||
| // Lookup table from method->interp entry | ||
| // The key is a string of the form <assembly name>_<method token> | ||
| // FIXME: Use a better encoding | ||
| w.Write ("static const char *wasm_native_to_interp_map[] = { "); | ||
| foreach (var cb in callbacks) { | ||
| var method = cb.Method; | ||
| string module_symbol = method.DeclaringType!.Module!.Assembly!.GetName()!.Name!.Replace(".", "_"); | ||
| string class_name = method.DeclaringType.Name; | ||
| string method_name = method.Name; | ||
| w.WriteLine ($"\"{module_symbol}_{class_name}_{method_name}\","); | ||
| } | ||
| foreach (var cb in callbacks) | ||
| w.WriteLine ($"\"{SymbolNameForMethod(cb.Method)}\","); | ||
| w.WriteLine ("};"); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of this.
For one thing it's incomplete - for nested classes we also need to replace '/' when it's in a class name. For another thing, C# allows many unicode characters in an identifier (https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names). And IL metadata actually doesn't seem to have any restrictions on identifiers - it's just sequences of bytes. I think we should do something like: convert the name to utf8; look at the bytes; for any bytes not in [0-9A-Za-z] replace them by "" or underscore and the byte hex code (ie
F☃will become "F_E2_98_83" https://www.compart.com/en/unicode/U+2603)