少年修仙传客户端基础资源
hch
2024-04-11 4c71d74b77c9eb62a0323698c9a0db3b641a917e
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
#include "il2cpp-config.h"
#include "icalls/mscorlib/System.Diagnostics/StackFrame.h"
#include "vm/StackTrace.h"
#include "gc/GarbageCollector.h"
 
using namespace mono::vm;
 
namespace mono
{
namespace icalls
{
namespace mscorlib
{
namespace System
{
namespace Diagnostics
{
    static bool IsCalledFromSystemDiagnosticsStackTrace(const StackFrames& stack)
    {
        for (StackFrames::const_iterator frame = stack.begin(); frame != stack.end(); ++frame)
            if (strcmp(mono_class_get_namespace(mono_unity_method_get_class(frame->method)), "System.Diagnostics") == 0 && strcmp(mono_class_get_name(mono_unity_method_get_class(frame->method)), "StackTrace") == 0)
                return true;
 
        return false;
    }
 
    static bool FrameNeedsSkipped(const MonoStackFrameInfo& frame)
    {
        return strcmp(mono_class_get_namespace(mono_unity_method_get_class(frame.method)), "System.Diagnostics") == 0 &&
            (strcmp(mono_class_get_name(mono_unity_method_get_class(frame.method)), "StackFrame") == 0 || strcmp(mono_class_get_name(mono_unity_method_get_class(frame.method)), "StackTrace") == 0);
    }
 
    bool StackFrame::get_frame_info(
        int32_t skip,
        bool needFileInfo,
        MonoReflectionMethod ** method,
        int32_t* iloffset,
        int32_t* native_offset,
        MonoString** file,
        int32_t* line,
        int32_t* column)
    {
        const int kSkippedFramesFromMSCorlibStackFrameMethods = 2;
        const int kSkippedFramesFromMSCorlibStackTraceMethods = 2;
 
        const StackFrames& stack = *StackTrace::GetStackFrames();
 
        // Always ignore the skipped frames from System.Diagnostics.StackFrame, as we know we are always called from it.
        // These frames might be inlined or optimized away by the C++ compiler, so we will inspect the actual stack
        // frames later to see if we need to add skipped frames back in for System.Diagnostics.StackFrame.
        skip -= kSkippedFramesFromMSCorlibStackFrameMethods;
 
 
        // Sometimes ignore the skipped frames from System.Diagnostics.StackTrace, as we may or may not be called from it.
        // These frames might be inlined or optimized away by the C++ compiler, so we will inspect the actual stack
        // frames later to see if we need to add skipped frames back in for System.Diagnostics.StackTrace.
        if (IsCalledFromSystemDiagnosticsStackTrace(stack))
            skip -= kSkippedFramesFromMSCorlibStackTraceMethods;
 
        // Now look in the actual stack trace to see if anything we ignored above is really there. We don't know what the C++
        // compile will do with these frames, so we need to inspect each frame and check.
        for (StackFrames::const_iterator frame = stack.begin(); frame != stack.end(); ++frame)
        {
            if (FrameNeedsSkipped(*frame))
                skip++;
        }
 
        // Finally, find the location in the stack we actually want to use by offsetting from the end of the stack the number of
        // frames we skipped, and offsetting it by one more to account for this icall itself.
        int64_t index = stack.size() - skip - 1;
        if (static_cast<uint64_t>(index) >= stack.size() || index < 0)
            return false;
 
        const MonoStackFrameInfo& info = stack[static_cast<size_t>(index)];
 
        *method = mono_unity_method_get_object(const_cast<MonoMethod*>(info.method));
        il2cpp::gc::GarbageCollector::SetWriteBarrier((void**)method);
 
        return true;
    }
} /* namespace Diagnostics */
} /* namespace System */
} /* namespace mscorlib */
} /* namespace icalls */
} /* namespace mono */