-
Notifications
You must be signed in to change notification settings - Fork 104
Expand file tree
/
Copy pathIl2cppContext.cs
More file actions
124 lines (105 loc) · 3.33 KB
/
Il2cppContext.cs
File metadata and controls
124 lines (105 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using dnlib.DotNet;
using ICSharpCode.SharpZipLib.Zip;
namespace il2cpp
{
public class Il2cppContext
{
public readonly ModuleDefMD Module;
public readonly ICorLibTypes CorLibTypes;
public readonly ModuleDef CorLibModule;
public readonly string RuntimeVersion;
internal TypeManager TypeMgr;
static Il2cppContext()
{
// 释放 GAC
string strGACPack = "il2cpp.gac.zip";
var zip = new FastZip();
zip.ExtractZip(Assembly.GetExecutingAssembly().GetManifestResourceStream(strGACPack),
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "gac/"),
FastZip.Overwrite.Always,
null, null, null, false, true);
}
public Il2cppContext(string imagePath)
{
Module = ModuleDefMD.Load(imagePath);
Debug.Assert(Module != null);
// 加载主模块
AssemblyResolver asmRes = new AssemblyResolver();
ModuleContext modCtx = new ModuleContext(asmRes);
asmRes.DefaultModuleContext = modCtx;
asmRes.EnableTypeDefCache = true;
asmRes.FindExactMatch = false;
asmRes.EnableFrameworkRedirect = true;
asmRes.FrameworkRedirectVersion = Module.RuntimeVersion;
Module.Context = modCtx;
Module.Context.AssemblyResolver.AddToCache(Module);
CorLibTypes = Module.CorLibTypes;
CorLibModule = CorLibTypes.Object.TypeRef.Resolve().Module;
RuntimeVersion = Module.RuntimeVersion;
Reset();
}
public void Reset()
{
// 初始化管理器
TypeMgr = new TypeManager(this);
}
public void AddEntry(MethodDef metDef)
{
TypeMgr?.ResolveMethodDef(metDef);
}
public void Resolve()
{
TypeMgr?.ResolveAll();
}
public GenerateResult Generate()
{
if (TypeMgr == null)
Reset();
return new GeneratorContext(TypeMgr).Generate();
}
public string GetRecordLogs()
{
return TypeMgr?.RecordLogs?.ToString();
}
public static void SaveToFolder(string folder, List<CompileUnit> units, HashSet<string> addUnitNames, string addParams = null)
{
Directory.CreateDirectory(folder);
HashSet<string> unitNames = new HashSet<string>(addUnitNames);
foreach (var unit in units)
{
if (!string.IsNullOrEmpty(unit.DeclCode))
{
string path = Path.Combine(folder, unit.Name + ".h");
File.WriteAllBytes(path, Encoding.UTF8.GetBytes(unit.DeclCode));
}
if (!string.IsNullOrEmpty(unit.ImplCode))
{
unitNames.Add(unit.Name);
string path = Path.Combine(folder, unit.Name + ".cpp");
File.WriteAllBytes(path, Encoding.UTF8.GetBytes(unit.ImplCode));
}
}
// 生成编译脚本
StringBuilder sb = new StringBuilder();
sb.AppendLine("@echo off");
sb.AppendFormat("BuildTheCode -addcflags \"-DGC_THREADS\" {0} il2cpp.cpp", addParams);
foreach (string unitName in unitNames)
sb.AppendFormat(" {0}.cpp", unitName);
sb.AppendLine();
File.WriteAllText(Path.Combine(folder, "build.cmd"), sb.ToString());
// 释放运行时代码
string strRuntimePack = "il2cpp.runtime.zip";
var zip = new FastZip();
zip.ExtractZip(Assembly.GetExecutingAssembly().GetManifestResourceStream(strRuntimePack),
folder,
FastZip.Overwrite.Always,
null, null, null, false, true);
}
}
}