Skip to content

Commit 87c8095

Browse files
author
kkin
committed
* generate warpper for all types / copy icall method for UnityEngine.dll
1 parent 29e3fbe commit 87c8095

12 files changed

Lines changed: 491 additions & 40 deletions

File tree

BindGenerater/BindGenerater.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@
7272
<Reference Include="System.Xml" />
7373
</ItemGroup>
7474
<ItemGroup>
75+
<Compile Include="Generater\AstNodeExtensions.cs" />
7576
<Compile Include="Generater\Binder.cs" />
7677
<Compile Include="Generater\AOTGenerater.cs" />
7778
<Compile Include="Generater\CSharp\CSCGenerater.cs" />
7879
<Compile Include="Generater\TestBinder.cs" />
7980
<Compile Include="Generater\CBinder.cs" />
80-
<Compile Include="Generater\CSharp\CustomOutputVisitor.cs" />
81+
<Compile Include="Generater\Visitor\CustomOutputVisitor.cs" />
8182
<Compile Include="Generater\CSharp\MethodResolver.cs" />
8283
<Compile Include="Generater\CSharp\TypeResolver.cs" />
8384
<Compile Include="Generater\CSharp\ClassGenerater.cs" />
@@ -94,6 +95,8 @@
9495
<Compile Include="Generater\C\ICallGenerater.cs" />
9596
<Compile Include="Generater\TypeDefinitionExtensions.cs" />
9697
<Compile Include="Generater\Utils.cs" />
98+
<Compile Include="Generater\Visitor\RetainFilter.cs" />
99+
<Compile Include="Generater\Visitor\TokenMapVisitor.cs" />
97100
<Compile Include="Program.cs" />
98101
<Compile Include="Properties\AssemblyInfo.cs" />
99102
</ItemGroup>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using ICSharpCode.Decompiler.CSharp.Syntax;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
public static class AstNodeExtensions
9+
{
10+
11+
public static string SimpleTypeName(this AstType tNode)
12+
{
13+
var simple = tNode as SimpleType;
14+
if (simple != null)
15+
return simple.Identifier;
16+
17+
return null;
18+
}
19+
20+
public static List<T> GetChildsOf<T>(this AstNode node) where T : AstNode
21+
{
22+
List<T> result = new List<T>();
23+
AstNode m = node as AstNode;
24+
foreach (AstNode n in m.Children)
25+
{
26+
if (n.GetType() == typeof(T))
27+
{
28+
result.Add(n as T);
29+
}
30+
result.AddRange(GetChildsOf<T>(n));
31+
}
32+
return result;
33+
34+
}
35+
public static T GetParentOf<T>(this AstNode node) where T : AstNode
36+
{
37+
AstNode m = node as AstNode;
38+
while (m.Parent != null)
39+
{
40+
if (m.Parent.GetType() == typeof(T))
41+
{
42+
return m.Parent as T;
43+
}
44+
m = m.Parent;
45+
}
46+
return default(T);
47+
}
48+
}

BindGenerater/Generater/Binder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public static void Bind(string dllPath)
6363
/*var file = Path.GetFileName(dllPath);
6464
if (IgnoreAssemblySet.Contains(file))
6565
return;*/
66+
var file = Path.GetFileName(dllPath);
6667

6768
DecompilerSetting = new DecompilerSettings(LanguageVersion.CSharp7);
6869
DecompilerSetting.ThrowOnAssemblyResolveErrors = false;
@@ -79,6 +80,7 @@ public static void Bind(string dllPath)
7980
ModuleDefinition module = ModuleDefinition.ReadModule(dllPath, parameters);
8081
moduleSet.Add(module);
8182
ICallGenerater.AddWrapperAssembly(module.Assembly.Name.Name);
83+
CSCGenerater.SetWrapper(file);
8284
CSCGenerater.AdapterCompiler.AddReference(module.Name);
8385
foreach(var refAssembly in module.AssemblyReferences )
8486
{

BindGenerater/Generater/CSharp/CSCGenerater.cs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,31 +48,44 @@ public class CSCGenerater
4848
private static string OutDir;
4949
private static string AdapterDir;
5050
private static HashSet<string> IgnoreRefSet = new HashSet<string>();
51+
private static Dictionary<string, CSCGenerater> WrapperDic = new Dictionary<string, CSCGenerater>();
5152

52-
public static void Init(string cscDir,string adapterDir,string outDir,HashSet<string> ignoreRefSet)
53+
public static void Init(string cscDir,string adapterDir,HashSet<string> ignoreRefSet)
5354
{
55+
string outDir = Path.Combine(adapterDir, "out");
5456
CSCPath = Path.Combine(cscDir, Utils.IsWin32() ? "csc.exe":"csc") ;
5557
OutDir = outDir;
5658
AdapterDir = adapterDir;
5759
IgnoreRefSet = ignoreRefSet;
5860
AdapterCompiler = new CSCGenerater(Path.Combine(outDir, "Adapter.gen.dll"));
59-
AdapterWrapperCompiler = new CSCGenerater(Path.Combine(outDir, "Adapter.wrapper.dll"));
60-
61+
6162
foreach(var file in AdapterSrc)
6263
AdapterCompiler.AddSource(Path.Combine(adapterDir,file));
64+
}
6365

64-
foreach (var file in AdapterWrapperSrc)
65-
AdapterWrapperCompiler.AddSource(Path.Combine(adapterDir, file));
66-
AdapterWrapperCompiler.AddDefine("WRAPPER_SIDE");
67-
if(!Utils.IsWin32())
68-
AdapterWrapperCompiler.AddDefine("IOS");
66+
public static void SetWrapper(string dllName)
67+
{
68+
if (!WrapperDic.TryGetValue(dllName,out AdapterWrapperCompiler))
69+
{
70+
AdapterWrapperCompiler = new CSCGenerater(Path.Combine(OutDir, "Adapter.wrapper.dll"));
71+
foreach (var file in AdapterWrapperSrc)
72+
AdapterWrapperCompiler.AddSource(Path.Combine(AdapterDir, file));
73+
AdapterWrapperCompiler.AddDefine("WRAPPER_SIDE");
74+
if (!Utils.IsWin32())
75+
AdapterWrapperCompiler.AddDefine("IOS");
76+
77+
WrapperDic[dllName] = AdapterWrapperCompiler;
78+
}
6979
}
7080

7181
public static void End()
7282
{
73-
7483
AdapterCompiler.Gen();
75-
AdapterWrapperCompiler.Gen();
84+
//AdapterWrapperCompiler.Gen();
85+
foreach(var wrapper in WrapperDic.Values)
86+
{
87+
wrapper.Gen();
88+
}
7689
}
7790

7891

BindGenerater/Generater/CSharp/ClassGenerater.cs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ public class ClassGenerater : CodeGenerater
2525

2626
public HashSet<string> RefNameSpace = new HashSet<string>();
2727

28+
Dictionary<int, AstNode> retainDic = new Dictionary<int, AstNode>();
2829
public ClassGenerater(TypeDefinition type, StreamWriter writer = null)
2930
{
31+
3032
genType = type;
3133
RefNameSpace.Add("PureScript.Mono");
3234

35+
CheckCopyOrignNodes();
3336
if (writer == null)
3437
{
3538
var filePath = Path.Combine(Binder.OutDir, $"Binder.{TypeFullName()}.cs");
@@ -83,7 +86,7 @@ public ClassGenerater(TypeDefinition type, StreamWriter writer = null)
8386

8487
foreach (PropertyDefinition prop in genType.Properties)
8588
{
86-
if (Utils.Filter(prop))
89+
if (Utils.Filter(prop) && !IsCopyOrignNode(prop))
8790
{
8891
var pt = prop.PropertyType.Resolve();
8992
if (pt.IsDelegate())
@@ -102,8 +105,9 @@ public ClassGenerater(TypeDefinition type, StreamWriter writer = null)
102105
{
103106
foreach (MethodDefinition method in genType.Methods)
104107
{
105-
// if (isFullValueType && (method.Name.StartsWith("op_") || method.Name == "Equals"))
106-
// continue;
108+
if (IsCopyOrignNode(method))
109+
continue;
110+
107111
if ((method.IsPublic || genType.IsInterface) && !method.IsGetter && !method.IsSetter && !method.IsAddOn && !method.IsRemoveOn && Utils.Filter(method))
108112
{
109113
methods.Add(new MethodGenerater(method));
@@ -139,9 +143,9 @@ public override void Gen()
139143
{
140144
base.Gen();
141145

142-
if (IsCopyOrign(genType))
146+
if (IsCopyOrignType(genType))
143147
{
144-
CopyGen(genType);
148+
CopyType(genType);
145149
CS.Writer.EndAll();
146150
return;
147151
}
@@ -210,27 +214,27 @@ public override void Gen()
210214
{
211215
m.Gen();
212216
}
217+
218+
GenCopyOrignNodes();
213219

214220
CS.Writer.EndAll();
215221
}
216222
}
217223

218-
bool IsCopyOrign(TypeDefinition type)
224+
bool IsCopyOrignType(TypeDefinition type)
219225
{
220226
if (type.IsGeneric() && !type.IsDelegate())
221227
return false;
222228
return type.IsValueType || type.IsEnum || type.IsDelegate() || type.IsInterface;
223229
}
224230

225-
void CopyGen(TypeDefinition type )
231+
void CopyType(TypeDefinition type )
226232
{
227-
228233
bool isNested = type.IsNested;
229234

230-
231235
HashSet<string> IgnoreNestType = new HashSet<string>();
232236

233-
if (!(isNested && IsCopyOrign(genType.DeclaringType)))
237+
if (!(isNested && IsCopyOrignType(genType.DeclaringType)))
234238
{
235239
var tName = type.FullName.Replace("/", "+");
236240
var name = new FullTypeName(tName);
@@ -299,7 +303,44 @@ void CopyGen(TypeDefinition type )
299303
}
300304

301305
}
306+
}
307+
308+
309+
void CheckCopyOrignNodes()
310+
{
311+
if (genType.Module.Name != "UnityEngine.CoreModule.dll")
312+
return;
313+
314+
var retainFilter = new RetainFilter(genType.MetadataToken.ToInt32());
315+
var tName = genType.FullName.Replace("/", "+");
316+
var name = new FullTypeName(tName);
317+
ITypeDefinition typeInfo = Binder.Decompiler.TypeSystem.MainModule.Compilation.FindType(name).GetDefinition();
318+
var tokenOfType = typeInfo.MetadataToken;
319+
var st = Binder.Decompiler.Decompile(tokenOfType);
320+
st.AcceptVisitor(retainFilter);
321+
retainDic = retainFilter.RetainDic;
322+
323+
if (retainDic.Count > 0)
324+
RefNameSpace.Add("System.Runtime.CompilerServices");
325+
}
326+
bool IsCopyOrignNode(MemberReference member)
327+
{
328+
if (retainDic.Count < 1)
329+
return false;
302330

331+
var token = member.MetadataToken.ToInt32();
332+
return token != 0 && retainDic.ContainsKey(token);
333+
}
334+
void GenCopyOrignNodes()
335+
{
336+
if (retainDic.Count < 1)
337+
return ;
338+
339+
CS.Writer.WriteLine("// -- copy orign code nodes --");
340+
CS.Writer.Flush();
341+
var outputVisitor = new CustomOutputVisitor(genType.IsNested,CS.Writer.GetWriter(), Binder.DecompilerSetting.CSharpFormattingOptions);
342+
foreach (var node in retainDic.Values)
343+
node.AcceptVisitor(outputVisitor);
303344
}
304345
}
305346
}

BindGenerater/Generater/CodeWriter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public CodeWriter(TextWriter _writer)
7373
UsePointer(CreateLinePoint("// auto gengerated !"));
7474
}
7575

76+
public TextWriter GetWriter() { return writer; }
77+
7678
public void Write(string str)
7779
{
7880
if (lines.Count == 0)

BindGenerater/Generater/Utils.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public static string BindMethodParamDefine(MethodDefinition method, bool declear
8686
return param;
8787
}
8888

89-
static string ReName(string name)
89+
public static string ReName(string name)
9090
{
9191
return name.Replace("::", "_").Replace(".", "_").Replace("/","_");
9292
}
@@ -751,6 +751,31 @@ public static bool IsWin32()
751751
return os.Platform.ToString().StartsWith("Win");
752752
}
753753

754+
public static void CollectMonoAssembly(string entry, string dir, HashSet<string> adapterSet,HashSet<string> outSet)
755+
{
756+
if (outSet.Contains(entry))
757+
return;
758+
759+
var file = Path.Combine(dir, entry);
760+
if (!File.Exists(file))
761+
return;
762+
763+
outSet.Add(entry);
764+
var assembly = AssemblyDefinition.ReadAssembly(file);
765+
var refs = assembly.MainModule.AssemblyReferences;
766+
foreach(var aref in refs)
767+
{
768+
var refName = aref.Name;
769+
if (!refName.EndsWith(".dll"))
770+
refName += ".dll";
771+
772+
if (adapterSet.Contains(refName))
773+
continue;
774+
775+
CollectMonoAssembly(refName, dir, adapterSet, outSet);
776+
}
777+
}
778+
754779
}
755780

756781
public class NameCounter

BindGenerater/Generater/CSharp/CustomOutputVisitor.cs renamed to BindGenerater/Generater/Visitor/CustomOutputVisitor.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ protected override void WriteAttributes(IEnumerable<AttributeSection> attributes
5252

5353
public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
5454
{
55-
56-
5755
if (isNested)
5856
{
5957
nestedUsing.Add(usingDeclaration.Namespace);

0 commit comments

Comments
 (0)