少年修仙传客户端基础资源
hch
2024-04-01 d01413b00ef631ac20347716b23818b0b811f65f
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
#pragma once
#include <tuple>
 
#include "vm/GlobalMetadata.h"
#include "vm/Exception.h"
#include "utils/HashUtils.h"
#include "metadata/Il2CppTypeHash.h"
#include "metadata/Il2CppTypeCompare.h"
 
#include "../CommonDef.h"
#include "MetadataDef.h"
 
namespace hybridclr
{
namespace metadata
{
    class Image;
 
#pragma region byteorder
 
    template<int N>
    inline void* GetAlignBorder(const void* pointer)
    {
        uint64_t p = (uint64_t)pointer;
        if (p % N == 0)
        {
            return (void*)pointer;
        }
        else
        {
            return (void*)((p + N - 1) / N * N);
        }
    }
 
    inline int32_t GetI1(const byte* data)
    {
        return *(int8_t*)data;
    }
 
    inline int16_t GetI2LittleEndian(const byte* data)
    {
#if SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS
        uint16_t value = *(uint16_t*)data;
#else
        uint16_t value = (uint16_t)data[0] | ((uint16_t)data[1] << 8);
#endif
        return (int16_t)value;
    }
 
    inline uint16_t GetU2LittleEndian(const byte* data)
    {
        return (uint16_t)GetI2LittleEndian(data);
    }
 
    inline int32_t GetI4LittleEndian(const byte* data)
    {
#if SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS
        uint32_t value = *(uint32_t*)data;
#else
        uint32_t value = (uint32_t)data[0]
            | ((uint32_t)data[1] << 8)
            | ((uint32_t)data[2] << 16)
            | ((uint32_t)data[3] << 24);
#endif
        return (int32_t)value;
    }
 
    inline int64_t GetI8LittleEndian(const byte* data)
    {
#if SUPPORT_MEMORY_NOT_ALIGMENT_ACCESS
        uint64_t value = *(uint64_t*)data;
#else
        uint64_t value = (uint64_t)data[0]
            + ((uint64_t)data[1] << 8)
            + ((uint64_t)data[2] << 16)
            + ((uint64_t)data[3] << 24)
            + ((uint64_t)data[4] << 32)
            + ((uint64_t)data[5] << 40)
            + ((uint64_t)data[6] << 48)
            + ((uint64_t)data[7] << 56);
#endif
        return value;
    }
 
    uint32_t GetNotZeroBitCount(uint64_t x);
 
#pragma endregion
 
 
#pragma region interpreter metadtata index
 
    const uint32_t kMetadataIndexBits = 22;
 
    const uint32_t kMetadataKindBits = 2;
 
    const uint32_t kMetadataKindShiftBits = 32 - kMetadataKindBits;
 
    const uint32_t kMetadataImageIndexShiftBits = kMetadataIndexBits;
 
    const uint32_t kMetadataImageIndexExtraShiftBitsA = 6;
    const uint32_t kMetadataImageIndexExtraShiftBitsB = 4;
    const uint32_t kMetadataImageIndexExtraShiftBitsC = 2;
    const uint32_t kMetadataImageIndexExtraShiftBitsD = 0;
    extern const uint32_t kMetadataImageIndexExtraShiftBitsArr[4];
 
    const uint32_t kMetadataIndexMaskA = (1 << (kMetadataIndexBits + kMetadataImageIndexExtraShiftBitsA)) - 1;
    const uint32_t kMetadataIndexMaskB = (1 << (kMetadataIndexBits + kMetadataImageIndexExtraShiftBitsB)) - 1;
    const uint32_t kMetadataIndexMaskC = (1 << (kMetadataIndexBits + kMetadataImageIndexExtraShiftBitsC)) - 1;
    const uint32_t kMetadataIndexMaskD = (1 << (kMetadataIndexBits + kMetadataImageIndexExtraShiftBitsD)) - 1;
    extern const uint32_t kMetadataIndexMaskArr[4];
 
    const uint32_t kMetadataImageIndexBits = 32 - kMetadataIndexBits;
 
    const uint32_t kMaxMetadataImageCount = (1 << kMetadataImageIndexBits);
 
    const uint32_t kMaxMetadataImageIndexWithoutKind = 1u << (kMetadataImageIndexBits - kMetadataKindBits);
 
    const uint32_t kInvalidImageIndex = 0;
 
    const int32_t kInvalidIndex = -1;
 
    inline int32_t DecodeMetadataKind(uint32_t index)
    {
        return index >> kMetadataKindShiftBits;
    }
 
    inline uint32_t DecodeImageIndex(int32_t index)
    {
        if (index == kInvalidIndex)
        {
            return 0;
        }
        uint32_t uindex = (uint32_t)index;
        uint32_t kind = uindex >> kMetadataKindShiftBits;
        return (uindex & ~kMetadataIndexMaskArr[kind]) >> kMetadataImageIndexShiftBits;
    }
 
    inline uint32_t DecodeMetadataIndex(int32_t index)
    {
        if (index == kInvalidIndex)
        {
            return kInvalidIndex;
        }
        uint32_t uindex = (uint32_t)index;
        uint32_t kind = uindex >> kMetadataKindShiftBits;
        return uindex & kMetadataIndexMaskArr[kind];
    }
 
    inline int32_t EncodeImageAndMetadataIndex(uint32_t imageIndex, int32_t rawIndex)
    {
        if (rawIndex == kInvalidIndex)
        {
            return kInvalidIndex;
        }
        IL2CPP_ASSERT(((imageIndex << kMetadataImageIndexShiftBits) & (uint32_t)rawIndex) == 0);
        return (imageIndex << kMetadataIndexBits) | (uint32_t)rawIndex;
    }
 
    inline bool IsInterpreterIndex(int32_t index)
    {
        //return DecodeImageIndex(index) != 0;
        return index != kInvalidIndex && ((uint32_t)index & ~kMetadataIndexMaskA) != 0;
    }
 
    inline bool IsInterpreterType(const Il2CppTypeDefinition* typeDefinition)
    {
        return IsInterpreterIndex(typeDefinition->byvalTypeIndex);
    }
 
    inline bool IsInterpreterType(const Il2CppClass* klass)
    {
        return IsInterpreterIndex(klass->image->token) && klass->rank == 0;
    }
 
    inline bool IsInterpreterImage(const Il2CppImage* image)
    {
        return IsInterpreterIndex(image->token);
    }
 
    inline bool IsPrologHasThis(uint32_t flags)
    {
        return flags & 0x20;
    }
 
    inline bool IsPrologExplicitThis(uint32_t flags)
    {
        return flags & 0x40;
    }
 
#pragma endregion
 
 
#pragma region method and klass
 
    inline bool IsInstanceField(const Il2CppType* type)
    {
        return (type->attrs & FIELD_ATTRIBUTE_STATIC) == 0;
    }
 
    inline bool IsInterpreterMethod(const MethodInfo* method)
    {
        return IsInterpreterType(method->klass);
    }
 
    inline bool IsInterpreterMethod(const Il2CppMethodDefinition* method)
    {
        return IsInterpreterIndex(method->declaringType);
    }
 
    inline bool IsInterpreterImplement(const MethodInfo* method)
    {
        return method->isInterpterImpl;
    }
 
    inline bool IsInstanceMethod(const MethodInfo* method)
    {
        return !(method->flags & METHOD_ATTRIBUTE_STATIC);
    }
 
    inline bool IsInstanceMethod(const Il2CppMethodDefinition* method)
    {
        return !(method->flags & METHOD_ATTRIBUTE_STATIC);
    }
 
    inline bool IsStaticMethod(const MethodInfo* method)
    {
        return (method->flags & METHOD_ATTRIBUTE_STATIC);
    }
 
    inline bool IsPrivateMethod(uint32_t flags)
    {
        return (flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE;
    }
 
    inline bool IsPublicMethod(uint32_t flags)
    {
        return (flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC;
    }
 
    inline bool IsGenericIns(const Il2CppType* type)
    {
        return type->type == IL2CPP_TYPE_GENERICINST;
    }
 
    inline bool IsVirtualMethod(uint32_t flags)
    {
        return flags & METHOD_ATTRIBUTE_VIRTUAL;
    }
 
    inline bool IsAbstractMethod(uint32_t flags)
    {
        return flags & METHOD_ATTRIBUTE_ABSTRACT;
    }
 
    inline bool IsNewSlot(uint32_t flags)
    {
        return flags & METHOD_ATTRIBUTE_NEW_SLOT;
    }
 
    inline bool IsSealed(uint32_t flags)
    {
        return flags & METHOD_ATTRIBUTE_FINAL;
    }
 
    inline bool IsInterface(uint32_t flags)
    {
        return flags & TYPE_ATTRIBUTE_INTERFACE;
    }
 
    bool IsValueType(const Il2CppType* type);
 
    inline bool IsValueType(const Il2CppTypeDefinition* typeDef)
    {
        return typeDef->bitfield & (1 << (il2cpp::vm::kBitIsValueType - 1));
    }
 
    inline bool IsEnumType(const Il2CppTypeDefinition* typeDef)
    {
        return (typeDef->bitfield >> (il2cpp::vm::kBitIsEnum - 1)) & 0x1;
    }
 
    inline const Il2CppTypeDefinition* GetUnderlyingTypeDefinition(const Il2CppType* type)
    {
        if (IsGenericIns(type))
        {
            return (Il2CppTypeDefinition*)type->data.generic_class->type->data.typeHandle;
        }
        else
        {
            return (Il2CppTypeDefinition*)type->data.typeHandle;
        }
    }
 
    inline void GetIl2CppTypeFromTypeDefinition(const Il2CppTypeDefinition* typeDef, Il2CppType& type)
    {
        type.type = typeDef->bitfield & (1 << (il2cpp::vm::kBitIsValueType - 1)) ? IL2CPP_TYPE_VALUETYPE : IL2CPP_TYPE_CLASS;
        type.data.typeHandle = (Il2CppMetadataTypeHandle)typeDef;
    }
 
    inline uint32_t GetActualArgumentNum(const MethodInfo* method)
    {
        return (uint32_t)method->parameters_count + (!(method->flags & METHOD_ATTRIBUTE_STATIC));
    }
 
    inline bool IsReturnVoidMethod(const MethodInfo* method)
    {
        return method->return_type->type == IL2CPP_TYPE_VOID;
    }
 
    inline bool IsVoidType(const Il2CppType* type)
    {
        return type->type == IL2CPP_TYPE_VOID;
    }
 
    inline const MethodInfo* GetUnderlyingMethodInfo(const MethodInfo* method)
    {
        return !method->genericMethod || method->is_generic ? method : method->genericMethod->methodDefinition;
    }
 
    inline bool IsChildTypeOfMulticastDelegate(const Il2CppClass* klass)
    {
        return klass->parent == il2cpp_defaults.multicastdelegate_class;
    }
 
    inline int32_t GetActualParamCount(const MethodInfo* methodInfo)
    {
        return IsInstanceMethod(methodInfo) ? (methodInfo->parameters_count + 1) : methodInfo->parameters_count;
    }
 
    inline int32_t GetFieldOffset(const FieldInfo* fieldInfo)
    {
        Il2CppClass* klass = fieldInfo->parent;
        return IS_CLASS_VALUE_TYPE(klass) ? (fieldInfo->offset - sizeof(Il2CppObject)) : fieldInfo->offset;
    }
 
    inline int32_t GetThreadStaticFieldOffset(const FieldInfo* fieldInfo)
    {
        return il2cpp::vm::MetadataCache::GetThreadLocalStaticOffsetForField(const_cast<FieldInfo*>(fieldInfo));
    }
 
    const Il2CppType* TryInflateIfNeed(const Il2CppType* selfType, const Il2CppGenericContext* genericContext, bool inflateMethodVars);
    const Il2CppType* TryInflateIfNeed(const Il2CppType* containerType, const Il2CppType* selfType);
 
    bool IsTypeSameByTypeIndex(TypeIndex t1, TypeIndex t2);
 
    bool IsTypeEqual(const Il2CppType* t1, const Il2CppType* t2);
 
    bool IsTypeGenericCompatible(const Il2CppType* t1, const Il2CppType* t2);
 
    bool IsOverrideMethod(const Il2CppType* type1, const Il2CppMethodDefinition* method1, const Il2CppType* type2, const Il2CppMethodDefinition* method2);
    bool IsOverrideMethodIgnoreName(const Il2CppType* type1, const Il2CppMethodDefinition* methodDef1, const Il2CppType* type2, const Il2CppMethodDefinition* methodDef2);
 
    const Il2CppMethodDefinition* ResolveMethodDefinition(const Il2CppType* type, const char* resolveMethodName, const MethodRefSig& resolveSig);
 
    const MethodInfo* GetMethodInfoFromMethodDef(const Il2CppType* type, const Il2CppMethodDefinition* methodDef);
 
    bool ResolveField(const Il2CppType* type, const char* resolveFieldName, Il2CppType* resolveFieldType, const Il2CppFieldDefinition*& retFieldDef);
 
    inline void ResolveFieldThrow(const Il2CppType* type, const char* resolveFieldName, Il2CppType* resolveFieldType, const Il2CppFieldDefinition*& retFieldDef)
    {
        if (!ResolveField(type, resolveFieldName, resolveFieldType, retFieldDef))
        {
            RaiseMissingFieldException(type, resolveFieldName);
        }
    }
 
    const Il2CppGenericContainer* GetGenericContainerFromIl2CppType(const Il2CppType* type);
 
    inline const Il2CppGenericContainer* GetGenericContainer(const MethodInfo* methodDef)
    {
        return methodDef->is_inflated ?
            (const Il2CppGenericContainer*)methodDef->genericMethod->methodDefinition->genericContainerHandle :
            (const Il2CppGenericContainer*)methodDef->genericContainerHandle;
    }
 
    bool IsMatchSigType(const Il2CppType* dstType, const Il2CppType* sigType, const Il2CppGenericContainer* klassGenericContainer, const Il2CppGenericContainer* methodGenericContainer);
 
    bool IsMatchMethodSig(const Il2CppMethodDefinition* methodDef, const MethodRefSig& resolveSig, const Il2CppGenericContainer* klassGenericContainer);
    bool IsMatchMethodSig(const MethodInfo* methodDef, const MethodRefSig& resolveSig, const Il2CppGenericContainer* klassGenericContainer);
    bool IsMatchMethodSig(const MethodInfo* methodDef, const MethodRefSig& resolveSig, const Il2CppType** klassInstArgv, const Il2CppType** methodInstArgv);
 
    inline Il2CppType* CloneIl2CppType(const Il2CppType* type)
    {
        Il2CppType* newType = (Il2CppType*)HYBRIDCLR_MALLOC(sizeof(Il2CppType));
        *newType = *type;
        return newType;
    }
 
    const Il2CppGenericInst* TryInflateGenericInst(const Il2CppGenericInst* inst, const Il2CppGenericContext* genericContext);
 
#pragma endregion
 
 
#pragma region misc
 
    const int32_t kMaxRetValueTypeStackObjectSize = 256;
 
    int32_t GetTypeValueSize(const Il2CppType* type);
 
    inline int32_t GetTypeValueSize(const Il2CppClass* klass)
    {
        if (IS_CLASS_VALUE_TYPE(klass))
        {
            return il2cpp::vm::Class::GetValueSize((Il2CppClass*)klass, nullptr);
        }
        else
        {
            return sizeof(Il2CppObject*);
        }
    }
 
    inline int32_t GetStackSizeByByteSize(int32_t size)
    {
        return (size + 7) / 8;
    }
 
    inline int32_t GetTypeValueStackObjectCount(const Il2CppType* type)
    {
        return (GetTypeValueSize(type) + 7) / 8;
    }
 
    inline void RaiseBadImageException(const char* msg = nullptr)
    {
        il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetBadImageFormatException(msg));
    }
#pragma endregion
 
    class Il2CppTypeHashShallow
    {
    public:
        size_t operator()(const Il2CppType* t1) const
        {
            size_t h = (size_t)t1->data.dummy;
            h = il2cpp::utils::HashUtils::Combine(h, t1->attrs);
            h = il2cpp::utils::HashUtils::Combine(h, (size_t)t1->type);
            h = il2cpp::utils::HashUtils::Combine(h, t1->byref);
            h = il2cpp::utils::HashUtils::Combine(h, t1->pinned);
#if HYBRIDCLR_UNITY_2021_OR_NEW
            h = il2cpp::utils::HashUtils::Combine(h, t1->valuetype);
#endif
            return h;
        }
    };
 
    class Il2CppTypeEqualityComparerShallow
    {
    public:
        bool operator()(const Il2CppType* t1, const Il2CppType* t2) const
        {
            return (t1->data.dummy == t2->data.dummy)
                && t1->type == t2->type
                && t1->attrs == t2->attrs
                && t1->byref == t2->byref
                && t1->pinned == t2->pinned
#if HYBRIDCLR_UNITY_2021_OR_NEW
                && t1->valuetype == t2->valuetype
#endif
                ;
        }
    };
 
 
    struct Il2CppTypeHash {
        size_t operator()(const Il2CppType* x) const noexcept {
            return il2cpp::metadata::Il2CppTypeHash::Hash(x);
        }
    };
 
    struct Il2CppTypeEqualTo
    {
        bool operator()(const Il2CppType* a, const Il2CppType* b) const {
            return il2cpp::metadata::Il2CppTypeEqualityComparer::AreEqual(a, b);
        }
    };
 
}
}