MLLIF
a MLIR-based Language to Language Interoperability Flyover
Loading...
Searching...
No Matches
MethodDefWriter.cs
Go to the documentation of this file.
1using Microsoft.CodeAnalysis;
4
6
7public readonly struct MethodDefWriter(IMethodSymbol symbol) : ICodeWriter
8{
9 public IEnumerable<WorkspaceDiagnostic> WriteTo(CodeWriter w, CodeContext ctx)
10 {
11 if (!symbol.IsTarget())
12 yield break;
13
14 var intParms = symbol.Parameters.Select(parm => $"{parm.Type.ToNativeInterfaceType()} {parm.Name}");
15 var intParmsStr = string.Join(", ", intParms);
16
17 var brParms = symbol.Parameters.Select(parm => $"{parm.Type.ToNativeBridgeType()} {parm.Name}");
18 if (!symbol.IsStatic)
19 brParms = brParms.Prepend("void*");
20 var brParmsStr = string.Join(", ", brParms);
21
22 var args = symbol.Parameters.Select(parm => parm.Name);
23 if (!symbol.IsStatic)
24 args = args.Prepend("_handle");
25 var argsStr = string.Join(", ", args);
26
27 var delegateName = $"__delegate{symbol.MangleName()}";
28 var delegateSymbol = symbol.ContainingType.GetMembers().SingleOrDefault(t => t.Name == delegateName);
29 if (delegateSymbol is not ITypeSymbol delegateType)
30 {
31 yield return BindingDiagnostic.Error(
32 ctx.Project, symbol,
33 $"error: corresponded delegate type of {symbol.ToDisplayString()} cannot be found");
34 yield break;
35 }
36
37 if (symbol.ReturnsVoid)
38 w.Write("void ");
39 else
40 {
41 w.Write(symbol.ReturnType.ToNativeInterfaceType(true));
42 w.Write(' ');
43 }
44
45 w.WriteLine(
46 $$"""
47 {{symbol.ContainingType.GetFullName("::")}}::{{symbol.Name}}({{intParmsStr}}) {
48 static {{symbol.ReturnType.ToNativeBridgeType()}} (*__proxy)({{brParmsStr}}) = nullptr;
49 if (!__proxy) {
50 ::s_get_function_pointer("{{symbol.ContainingType.GetFullyQualifiedName()}}", "{{symbol.MangleName()}}", "{{delegateType.GetFullyQualifiedName()}}", nullptr, nullptr, reinterpret_cast<void**>(&__proxy));
51 }
52 """);
53 w.Indent++;
54
55 if (!symbol.ReturnsVoid)
56 w.Write("return ");
57 w.WriteLine($"__proxy({argsStr});");
58
59 w.Indent--;
60
61 w.WriteLine("}");
62 w.WriteLine();
63 }
64}
class BindingDiagnostic(WorkspaceDiagnosticKind kind, string message, Project project, Document? document)