少年修仙传客户端基础资源
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
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
#include "il2cpp-api.h"
#include "il2cpp-config.h"
#include "utils/dynamic_array.h"
#include "vm/ThreadPoolMs.h"
#include "vm/Domain.h"
#include "vm/Array.h"
#include "vm/Object.h"
#include "vm/Runtime.h"
#include "os/Atomic.h"
#include "gc/WriteBarrier.h"
#include "mono/ThreadPool/threadpool-ms.h"
 
namespace il2cpp
{
namespace vm
{
    Il2CppAsyncResult* ThreadPoolMs::DelegateBeginInvoke(Il2CppDelegate* delegate, void** params, Il2CppDelegate* asyncCallback, Il2CppObject* state)
    {
#if IL2CPP_TINY
        IL2CPP_ASSERT(0 && "ThreadPoolMs::DelegateBeginInvoke should not be called with the Tiny profile.");
        return NULL;
#else
        int numParams = delegate->method->parameters_count;
        il2cpp::utils::dynamic_array<void*> newParams(numParams + 2);
        for (int i = 0; i < numParams; ++i)
            newParams[i] = params[i];
 
        newParams[numParams] = asyncCallback;
        newParams[numParams + 1] = state;
 
        return threadpool_ms_begin_invoke(il2cpp::vm::Domain::GetCurrent(), (Il2CppObject*)delegate, const_cast<MethodInfo*>(delegate->method), newParams.data());
#endif
    }
 
    Il2CppObject* ThreadPoolMs::DelegateEndInvoke(Il2CppAsyncResult* asyncResult, void **out_args)
    {
#if IL2CPP_TINY
        IL2CPP_ASSERT(0 && "ThreadPoolMs::DelegateEndInvoke should not be called with the Tiny profile.");
        return NULL;
#else
        Il2CppArray *arrayOutArgs;
        Il2CppObject *exc, *retVal;
 
        retVal = threadpool_ms_end_invoke(asyncResult, &arrayOutArgs, &exc);
 
        if (exc)
            il2cpp_raise_exception((Il2CppException*)exc);
 
        if (out_args)
        {
            const MethodInfo *method = asyncResult->async_delegate->method;
            void** outArgsPtr = (void**)il2cpp_array_addr(arrayOutArgs, Il2CppObject*, 0);
 
            il2cpp_array_size_t arrayOutArgsIndex = 0;
            for (size_t methodParameterIndex = 0; methodParameterIndex < method->parameters_count; methodParameterIndex++)
            {
                const Il2CppType* paramType = method->parameters[methodParameterIndex].parameter_type;
 
                // Assume that arrayOutArgs only contains parameters that are passed by reference.
                if (!paramType->byref)
                    continue;
                IL2CPP_ASSERT(arrayOutArgsIndex < arrayOutArgs->max_length);
                Il2CppClass *paramClass = il2cpp_class_from_type(paramType);
 
                if (paramClass->valuetype)
                {
                    IL2CPP_ASSERT(paramClass->native_size > 0 && "EndInvoke: Invalid native_size found when trying to copy a value type in the out_args.");
 
                    // NOTE(gab): in case of value types, we need to copy the data over.
                    memcpy(out_args[arrayOutArgsIndex], il2cpp::vm::Object::Unbox((Il2CppObject*)outArgsPtr[arrayOutArgsIndex]), paramClass->native_size);
                }
                else
                {
                    *((void**)out_args[arrayOutArgsIndex]) = outArgsPtr[arrayOutArgsIndex];
                }
                arrayOutArgsIndex++;
            }
        }
 
        return retVal;
#endif
    }
 
    Il2CppObject* ThreadPoolMs::MessageInvoke(Il2CppObject *target, Il2CppMethodMessage *msg, Il2CppObject **exc, Il2CppArray **out_args)
    {
        static Il2CppClass *object_array_klass = NULL;
        MethodInfo *method;
        Il2CppObject *ret;
        Il2CppArray *arr;
        int i, j, outarg_count = 0;
 
        method = (MethodInfo*)msg->method->method;
 
        for (i = 0; i < method->parameters_count; i++)
        {
            if (method->parameters[i].parameter_type->byref)
                outarg_count++;
        }
 
        if (!object_array_klass)
        {
            Il2CppClass *klass;
 
            klass = il2cpp_array_class_get(il2cpp_defaults.object_class, 1);
            IL2CPP_ASSERT(klass);
 
            os::Atomic::FullMemoryBarrier();
            object_array_klass = klass;
        }
 
        arr = il2cpp_array_new(object_array_klass, outarg_count);
 
        il2cpp::gc::WriteBarrier::GenericStore(out_args, (Il2CppObject*)arr);
        il2cpp::gc::WriteBarrier::GenericStore(exc, NULL);
 
        ret = vm::Runtime::InvokeArray(method, method->klass->valuetype ? il2cpp_object_unbox(target) : target, method->parameters_count > 0 ? msg->args : NULL, (Il2CppException**)exc);
 
        for (i = 0, j = 0; i < method->parameters_count; i++)
        {
            if (method->parameters[i].parameter_type->byref)
            {
                Il2CppObject* arg;
                arg = (Il2CppObject*)il2cpp_array_get(msg->args, void*, i);
                il2cpp_array_setref(*out_args, j, arg);
                j++;
            }
        }
 
        return ret;
    }
 
    void ThreadPoolMs::Suspend()
    {
        threadpool_ms_suspend();
    }
 
    void ThreadPoolMs::Resume()
    {
        threadpool_ms_resume();
    }
} /* namespace vm */
} /* namespace il2cpp */