• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SamboyCoding / Cpp2IL / 12324180199

13 Dec 2024 10:46PM UTC coverage: 27.497% (-0.3%) from 27.79%
12324180199

push

github

SamboyCoding
Core: Fix more test failures

1251 of 6374 branches covered (19.63%)

Branch coverage included in aggregate %.

18 of 21 new or added lines in 1 file covered. (85.71%)

429 existing lines in 16 files now uncovered.

3360 of 10395 relevant lines covered (32.32%)

124828.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

32.52
/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs
1
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics.CodeAnalysis;
4
using System.Reflection;
5
using Cpp2IL.Core.Graphs;
6
using Cpp2IL.Core.ISIL;
7
using Cpp2IL.Core.Graphs.Processors;
8
using Cpp2IL.Core.Logging;
9
using Cpp2IL.Core.Utils;
10
using LibCpp2IL;
11
using LibCpp2IL.Metadata;
12
using StableNameDotNet.Providers;
13
using System.Linq;
14

15
namespace Cpp2IL.Core.Model.Contexts;
16

17
/// <summary>
18
/// Represents one method within the application. Can be analyzed to attempt to reconstruct the function body.
19
/// </summary>
20
public class MethodAnalysisContext : HasCustomAttributesAndName, IMethodInfoProvider
21
{
22
    /// <summary>
23
    /// The underlying metadata for the method.
24
    ///
25
    /// Nullable iff this is a subclass.
26
    /// </summary>
27
    public readonly Il2CppMethodDefinition? Definition;
28

29
    /// <summary>
30
    /// The analysis context for the declaring type of this method.
31
    /// </summary>
32
    public readonly TypeAnalysisContext? DeclaringType;
33

34
    /// <summary>
35
    /// The address of this method as defined in the underlying metadata.
36
    /// </summary>
37
    public virtual ulong UnderlyingPointer => Definition?.MethodPointer ?? throw new("Subclasses of MethodAnalysisContext should override UnderlyingPointer");
488,988!
38

39
    public ulong Rva => UnderlyingPointer == 0 || LibCpp2IlMain.Binary == null ? 0 : LibCpp2IlMain.Binary.GetRva(UnderlyingPointer);
×
40

41
    /// <summary>
42
    /// The raw method body as machine code in the active instruction set.
43
    /// </summary>
UNCOV
44
    public Memory<byte> RawBytes => rawMethodBody ??= InitRawBytes();
×
45

46
    /// <summary>
47
    /// The first-stage-analyzed Instruction-Set-Independent Language Instructions.
48
    /// </summary>
49
    public List<InstructionSetIndependentInstruction>? ConvertedIsil;
50

51
    /// <summary>
52
    /// The control flow graph for this method, if one is built.
53
    /// </summary>
54
    public ISILControlFlowGraph? ControlFlowGraph;
55

56
    public List<ParameterAnalysisContext> Parameters = [];
394,026✔
57

58
    /// <summary>
59
    /// Does this method return void?
60
    /// </summary>
61
    public virtual bool IsVoid => (Definition?.ReturnType?.ToString() ?? throw new("Subclasses of MethodAnalysisContext should override IsVoid")) == "System.Void";
×
62

63
    public virtual bool IsStatic => Definition?.IsStatic ?? throw new("Subclasses of MethodAnalysisContext should override IsStatic");
×
64

65
    protected override int CustomAttributeIndex => Definition?.customAttributeIndex ?? throw new("Subclasses of MethodAnalysisContext should override CustomAttributeIndex if they have custom attributes");
174,060!
66

67
    public override AssemblyAnalysisContext CustomAttributeAssembly => DeclaringType?.DeclaringAssembly ?? throw new("Subclasses of MethodAnalysisContext should override CustomAttributeAssembly if they have custom attributes");
322,971!
68

69
    public override string DefaultName => Definition?.Name ?? throw new("Subclasses of MethodAnalysisContext should override DefaultName");
22!
70

71
    public string FullName => DeclaringType == null ? Name : $"{DeclaringType.FullName}::{Name}";
22!
72

73
    public string FullNameWithSignature => $"{ReturnTypeContext.FullName} {FullName}({string.Join(", ", Parameters.Select(p => p.HumanReadableSignature))})";
×
74

75
    public virtual MethodAttributes Attributes => Definition?.Attributes ?? throw new("Subclasses of MethodAnalysisContext should override Attributes");
×
76

77
    public TypeAnalysisContext? InjectedReturnType { get; set; }
290,901✔
78

79
    public int ParameterCount => Parameters.Count;
×
80

81
    public int GenericParameterCount => Definition?.GenericContainer?.genericParameterCount ?? 0;
×
82

83
    //TODO Support custom attributes on return types (v31 feature)
84
    public TypeAnalysisContext ReturnTypeContext => InjectedReturnType ?? DeclaringType!.DeclaringAssembly.ResolveIl2CppType(Definition!.RawReturnType!);
145,389✔
85
    
86
    protected Memory<byte>? rawMethodBody;
87

88

89
    private static readonly List<IBlockProcessor> blockProcessors =
×
90
    [
×
91
        new MetadataProcessor(),
×
92
        new CallProcessor()
×
93
    ];
×
94

95
    public MethodAnalysisContext(Il2CppMethodDefinition? definition, TypeAnalysisContext parent) : base(definition?.token ?? 0, parent.AppContext)
394,026✔
96
    {
97
        DeclaringType = parent;
394,026✔
98
        Definition = definition;
394,026✔
99

100
        if (Definition != null)
394,026✔
101
        {
102
            InitCustomAttributeData();
248,514✔
103

104
            for (var i = 0; i < Definition.InternalParameterData!.Length; i++)
1,075,284✔
105
            {
106
                var parameterDefinition = Definition.InternalParameterData![i];
289,128✔
107
                Parameters.Add(new(parameterDefinition, i, this));
289,128✔
108
            }
109
        }
110
        else
111
            rawMethodBody = Array.Empty<byte>();
145,512✔
112
    }
145,512✔
113

114
    [MemberNotNull(nameof(rawMethodBody))]
115
    public void EnsureRawBytes()
116
    {
117
        rawMethodBody ??= InitRawBytes();
248,514✔
118
    }
248,514✔
119

120
    private Memory<byte> InitRawBytes()
121
    {
122
        //Some abstract methods (on interfaces, no less) apparently have a body? Unity doesn't support default interface methods so idk what's going on here.
123
        //E.g. UnityEngine.Purchasing.AppleCore.dll: UnityEngine.Purchasing.INativeAppleStore::SetUnityPurchasingCallback on among us (itch.io build)
124
        if (Definition != null && Definition.MethodPointer != 0 && !Definition.Attributes.HasFlag(MethodAttributes.Abstract))
248,514✔
125
        {
126
            var ret = AppContext.InstructionSet.GetRawBytesForMethod(this, false);
240,474✔
127

128
            if (ret.Length == 0)
240,474✔
129
            {
130
                Logger.VerboseNewline("\t\t\tUnexpectedly got 0-byte method body for " + this + $". Pointer was 0x{Definition.MethodPointer:X}", "MAC");
22!
131
            }
132

133
            return ret;
240,474✔
134
        }
135
        else
136
            return Array.Empty<byte>();
8,040✔
137
    }
138

UNCOV
139
    protected MethodAnalysisContext(ApplicationAnalysisContext context) : base(0, context)
×
140
    {
UNCOV
141
        rawMethodBody = Array.Empty<byte>();
×
UNCOV
142
    }
×
143

144
    [MemberNotNull(nameof(ConvertedIsil))]
145
    public void Analyze()
146
    {
147
        if (ConvertedIsil != null)
×
148
            return;
×
149

150
        if (UnderlyingPointer == 0)
×
151
        {
152
            ConvertedIsil = [];
×
153
            return;
×
154
        }
155

156
        ConvertedIsil = AppContext.InstructionSet.GetIsilFromMethod(this);
×
157

158
        if (ConvertedIsil.Count == 0)
×
159
            return; //Nothing to do, empty function
×
160

161
        ControlFlowGraph = new ISILControlFlowGraph();
×
162
        ControlFlowGraph.Build(ConvertedIsil);
×
163

164
        // Post step to convert metadata usage. Ldstr Opcodes etc.
165
        foreach (var block in ControlFlowGraph.Blocks)
×
166
        {
167
            foreach (var converter in blockProcessors)
×
168
            {
169
                converter.Process(this, block);
×
170
            }
171
        }
172
    }
×
173

174
    public void ReleaseAnalysisData()
175
    {
176
        ConvertedIsil = null;
×
177
        ControlFlowGraph = null;
×
178
    }
×
179

180
    public override string ToString() => $"Method: {FullName}";
22✔
181

182
    #region StableNameDot implementation
183

184
    ITypeInfoProvider IMethodInfoProvider.ReturnType =>
185
        Definition!.RawReturnType!.ThisOrElementIsGenericParam()
×
186
            ? new GenericParameterTypeInfoProviderWrapper(Definition.RawReturnType!.GetGenericParamName())
×
187
            : TypeAnalysisContext.GetSndnProviderForType(AppContext, Definition!.RawReturnType);
×
188

189
    IEnumerable<IParameterInfoProvider> IMethodInfoProvider.ParameterInfoProviders => Parameters;
×
190

191
    string IMethodInfoProvider.MethodName => Name;
×
192

193
    MethodAttributes IMethodInfoProvider.MethodAttributes => Attributes;
×
194

195
    MethodSemantics IMethodInfoProvider.MethodSemantics
196
    {
197
        get
198
        {
199
            if (DeclaringType != null)
×
200
            {
201
                //This one is a bit trickier, as il2cpp doesn't use semantics.
202
                foreach (var prop in DeclaringType.Properties)
×
203
                {
204
                    if (prop.Getter == this)
×
205
                        return MethodSemantics.Getter;
×
206
                    if (prop.Setter == this)
×
207
                        return MethodSemantics.Setter;
×
208
                }
209

210
                foreach (var evt in DeclaringType.Events)
×
211
                {
212
                    if (evt.Adder == this)
×
213
                        return MethodSemantics.AddOn;
×
214
                    if (evt.Remover == this)
×
215
                        return MethodSemantics.RemoveOn;
×
216
                    if (evt.Invoker == this)
×
217
                        return MethodSemantics.Fire;
×
218
                }
219
            }
220

221
            return 0;
×
222
        }
×
223
    }
224

225
    #endregion
226
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc