Skip to content

Commit 94c933f

Browse files
committed
refactor: inheritance graphs, delegate params, context checks
- MethodInheritanceGraph now uses rooted DAGs for robust traversal, leaf detection, and acyclicity validation - Adjacency maps and body-filtered implementation graphs added; legacy fields preserved - MethodCallGraph uses caller consistently and expands interface/virtual resolution via GetRuntimeMethods - Static constructor patching improves context-bound method detection, including lambda/iterator analysis - Fixed static field modification chain logic bug - Delegate context injection logic updated for correctness
1 parent 477fe1f commit 94c933f

15 files changed

Lines changed: 724 additions & 80 deletions

src/OTAPI.UnifiedServerProcess/Core/Analysis/MethodCallAnalysis/MethodCallGraph.cs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ public MethodCallGraph(ILogger logger, ModuleDefinition module, DelegateInvocati
3434
var unexpectedImplMissMethods = new Dictionary<string, MethodDefinition>();
3535

3636
foreach (var type in module.GetAllTypes()) {
37-
foreach (var method in type.Methods) {
38-
if (!method.HasBody)
37+
foreach (var caller in type.Methods) {
38+
if (!caller.HasBody)
3939
continue;
4040

41-
var methodId = method.GetIdentifier();
41+
var methodId = caller.GetIdentifier();
4242

43-
var body = method.Body;
43+
var body = caller.Body;
4444

45-
var jumpSites = this.GetMethodJumpSites(method);
45+
var jumpSites = this.GetMethodJumpSites(caller);
4646

4747
foreach (var instruction in body.Instructions) {
4848
if (instruction.OpCode != OpCodes.Call && instruction.OpCode != OpCodes.Callvirt && instruction.OpCode != OpCodes.Newobj)
@@ -69,30 +69,30 @@ public MethodCallGraph(ILogger logger, ModuleDefinition module, DelegateInvocati
6969
taskRunDeleIndex = 0;
7070
}
7171
if (taskRunDeleIndex != -1) {
72-
foreach (var path in MonoModCommon.Stack.AnalyzeParametersSources(method, instruction, jumpSites)) {
73-
var loadDelegate = MonoModCommon.Stack.AnalyzeStackTopTypeAllPaths(method, path.ParametersSources[taskRunDeleIndex].Instructions.Last(), jumpSites)
72+
foreach (var path in MonoModCommon.Stack.AnalyzeParametersSources(caller, instruction, jumpSites)) {
73+
var loadDelegate = MonoModCommon.Stack.AnalyzeStackTopTypeAllPaths(caller, path.ParametersSources[taskRunDeleIndex].Instructions.Last(), jumpSites)
7474
.Single();
75-
if (!invocationGraph.TracedDelegates.TryGetValue(DelegateInvocationData.GenerateStackKey(method, loadDelegate.RealPushValueInstruction), out var data)) {
75+
if (!invocationGraph.TracedDelegates.TryGetValue(DelegateInvocationData.GenerateStackKey(caller, loadDelegate.RealPushValueInstruction), out var data)) {
7676
continue;
7777
}
7878
AddMethod(MethodReferenceData.DelegateCall(calleeDef, [.. data.Invocations.Values]));
7979
}
8080
}
8181

82-
IEnumerable<MethodDefinition> methods = [method];
82+
IEnumerable<MethodDefinition> methods = [caller];
8383
if (calleeRef.HasThis && calleeRef.Name != ".ctor") {
8484
HashSet<MethodDefinition> tempMethods = [];
85-
foreach (var path in MonoModCommon.Stack.AnalyzeParametersSources(method, instruction, jumpSites)) {
86-
foreach (var stackTop in MonoModCommon.Stack.AnalyzeStackTopTypeAllPaths(method, path.ParametersSources[0].Instructions.Last(), jumpSites)) {
85+
foreach (var path in MonoModCommon.Stack.AnalyzeParametersSources(caller, instruction, jumpSites)) {
86+
foreach (var stackTop in MonoModCommon.Stack.AnalyzeStackTopTypeAllPaths(caller, path.ParametersSources[0].Instructions.Last(), jumpSites)) {
8787
var stackType = stackTop.StackTopType?.TryResolve();
8888
if (stackType is null) {
8989
continue;
9090
}
9191
if (stackType.Scope.Name != module.Name) {
92-
logger.Warn(this, 1, $"Ignore: [type:{stackType.Name}|callee: {calleeRef.GetDebugName()}] by {method.GetDebugName()}");
92+
logger.Warn(this, 1, $"Ignore: [type:{stackType.Name}|callee: {calleeRef.GetDebugName()}] by {caller.GetDebugName()}");
9393
continue;
9494
}
95-
var m = stackType?.Methods.FirstOrDefault(m =>
95+
var m = stackType?.GetRuntimeMethods(true).FirstOrDefault(m =>
9696
m.GetIdentifier(false).EndsWith("." + calleeDef.GetIdentifier(false)) || // implict interface impl
9797
m.GetIdentifier(false) == calleeDef.GetIdentifier(false));
9898
if (m is not null) {
@@ -106,7 +106,7 @@ public MethodCallGraph(ILogger logger, ModuleDefinition module, DelegateInvocati
106106
HashSet<MethodDefinition> implementations = [];
107107
bool isDelegateInvocation = false;
108108
foreach (var m in methods) {
109-
foreach (var impl in this.GetMethodImplementations(method, instruction, jumpSites, out isDelegateInvocation, true)) {
109+
foreach (var impl in this.GetMethodImplementations(caller, instruction, jumpSites, out isDelegateInvocation, true)) {
110110
implementations.Add(impl);
111111
}
112112
}
@@ -130,10 +130,10 @@ public MethodCallGraph(ILogger logger, ModuleDefinition module, DelegateInvocati
130130
usedByMethods = [];
131131
usedByMethodsDict[calleeId] = usedByMethods;
132132
}
133-
usedByMethods.Add(method);
133+
usedByMethods.Add(caller);
134134

135135
void AddMethod(MethodReferenceData add) {
136-
// Update usedMethodsDict for the tail method
136+
// Update usedMethodsDict for the tail caller
137137
if (!usedMethodsDict.TryGetValue(methodId, out var usedMethods)) {
138138
usedMethods = [];
139139
usedMethodsDict[methodId] = usedMethods;
@@ -142,12 +142,12 @@ void AddMethod(MethodReferenceData add) {
142142

143143
var implId = add.DirectlyCalledMethod.GetIdentifier();
144144

145-
// Update usedByMethodsDict for the implementation method
145+
// Update usedByMethodsDict for the implementation caller
146146
if (!usedByMethodsDict.TryGetValue(implId, out var usedByMethods)) {
147147
usedByMethods = [];
148148
usedByMethodsDict[implId] = usedByMethods;
149149
}
150-
usedByMethods.Add(method);
150+
usedByMethods.Add(caller);
151151
}
152152
}
153153
}
@@ -184,8 +184,7 @@ void AddMethod(MethodReferenceData add) {
184184
MethodDefinition[] usedByMethods = usedByMethodsDict.TryGetValue(methodId, out var ubm)
185185
? [.. ubm]
186186
: [];
187-
188-
methodCallsBuilder.Add(method.GetIdentifier(), new MethodCallData(method, usedMethods, usedByMethods));
187+
methodCallsBuilder.Add(methodId, new MethodCallData(method, usedMethods, usedByMethods));
189188
}
190189

191190
MediatedCallGraph = methodCallsBuilder;

0 commit comments

Comments
 (0)