Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches

◆ CreateObjectArrayDelegateRefEmit()

static Delegate System.Dynamic.Utils.DelegateHelpers.CreateObjectArrayDelegateRefEmit ( Type delegateType,
Func< object[], object > handler )
inlinestaticprivate

Definition at line 134 of file DelegateHelpers.cs.

135 {
136 if (!s_thunks.TryGetValue(delegateType, out var value))
137 {
138 MethodInfo invokeMethod = delegateType.GetInvokeMethod();
139 Type returnType = invokeMethod.ReturnType;
140 bool flag = returnType != typeof(void);
141 ParameterInfo[] parametersCached = invokeMethod.GetParametersCached();
142 value = GetCSharpThunk(returnType, flag, parametersCached);
143 if (value == null)
144 {
145 int value2 = Interlocked.Increment(ref s_ThunksCreated);
146 Type[] array = new Type[parametersCached.Length + 1];
147 array[0] = typeof(Func<object[], object>);
148 StringBuilder stringBuilder = new StringBuilder();
149 stringBuilder.Append("Thunk");
150 stringBuilder.Append(value2);
151 if (flag)
152 {
153 stringBuilder.Append("ret_");
154 stringBuilder.Append(returnType.Name);
155 }
156 for (int i = 0; i < parametersCached.Length; i++)
157 {
158 stringBuilder.Append('_');
159 stringBuilder.Append(parametersCached[i].ParameterType.Name);
160 array[i + 1] = parametersCached[i].ParameterType;
161 }
162 DynamicMethod dynamicMethod = new DynamicMethod(stringBuilder.ToString(), returnType, array);
163 value = dynamicMethod;
164 ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
165 LocalBuilder local = iLGenerator.DeclareLocal(typeof(object[]));
166 LocalBuilder local2 = iLGenerator.DeclareLocal(typeof(object));
167 if (parametersCached.Length == 0)
168 {
169 iLGenerator.Emit(OpCodes.Call, s_ArrayEmpty);
170 }
171 else
172 {
173 iLGenerator.Emit(OpCodes.Ldc_I4, parametersCached.Length);
174 iLGenerator.Emit(OpCodes.Newarr, typeof(object));
175 }
176 iLGenerator.Emit(OpCodes.Stloc, local);
177 bool flag2 = false;
178 for (int j = 0; j < parametersCached.Length; j++)
179 {
180 bool isByRef = parametersCached[j].ParameterType.IsByRef;
181 Type type = parametersCached[j].ParameterType;
182 if (isByRef)
183 {
185 }
186 flag2 = flag2 || isByRef;
187 iLGenerator.Emit(OpCodes.Ldloc, local);
188 iLGenerator.Emit(OpCodes.Ldc_I4, j);
189 iLGenerator.Emit(OpCodes.Ldarg, j + 1);
190 if (isByRef)
191 {
192 iLGenerator.Emit(OpCodes.Ldobj, type);
193 }
195 iLGenerator.Emit(OpCodes.Box, cls);
196 iLGenerator.Emit(OpCodes.Stelem_Ref);
197 }
198 if (flag2)
199 {
200 iLGenerator.BeginExceptionBlock();
201 }
202 iLGenerator.Emit(OpCodes.Ldarg_0);
203 iLGenerator.Emit(OpCodes.Ldloc, local);
204 iLGenerator.Emit(OpCodes.Callvirt, s_FuncInvoke);
205 iLGenerator.Emit(OpCodes.Stloc, local2);
206 if (flag2)
207 {
208 iLGenerator.BeginFinallyBlock();
209 for (int k = 0; k < parametersCached.Length; k++)
210 {
211 if (parametersCached[k].ParameterType.IsByRef)
212 {
213 Type elementType = parametersCached[k].ParameterType.GetElementType();
214 iLGenerator.Emit(OpCodes.Ldarg, k + 1);
215 iLGenerator.Emit(OpCodes.Ldloc, local);
216 iLGenerator.Emit(OpCodes.Ldc_I4, k);
217 iLGenerator.Emit(OpCodes.Ldelem_Ref);
218 iLGenerator.Emit(OpCodes.Unbox_Any, elementType);
219 iLGenerator.Emit(OpCodes.Stobj, elementType);
220 }
221 }
222 iLGenerator.EndExceptionBlock();
223 }
224 if (flag)
225 {
226 iLGenerator.Emit(OpCodes.Ldloc, local2);
227 iLGenerator.Emit(OpCodes.Unbox_Any, ConvertToBoxableType(returnType));
228 }
229 iLGenerator.Emit(OpCodes.Ret);
230 }
231 s_thunks[delegateType] = value;
232 }
233 return value.CreateDelegate(delegateType, handler);
234 }
static MethodInfo GetCSharpThunk(Type returnType, bool hasReturnValue, ParameterInfo[] parameters)
static readonly MethodInfo s_ArrayEmpty
static readonly CacheDict< Type, MethodInfo > s_thunks
static readonly MethodInfo s_FuncInvoke
virtual LocalBuilder DeclareLocal(Type localType)
virtual void Emit(OpCode opcode)
static readonly OpCode Unbox_Any
Definition OpCodes.cs:329
static readonly OpCode Callvirt
Definition OpCodes.cs:225
static readonly OpCode Stloc
Definition OpCodes.cs:429
static readonly OpCode Ldobj
Definition OpCodes.cs:229
static readonly OpCode Ldc_I4
Definition OpCodes.cs:69
static readonly OpCode Stelem_Ref
Definition OpCodes.cs:323
static readonly OpCode Ldelem_Ref
Definition OpCodes.cs:307
static readonly OpCode Stobj
Definition OpCodes.cs:257
static readonly OpCode Call
Definition OpCodes.cs:83
static readonly OpCode Ret
Definition OpCodes.cs:87
static readonly OpCode Ldloc
Definition OpCodes.cs:425
static readonly OpCode Box
Definition OpCodes.cs:279
static readonly OpCode Ldarg_0
Definition OpCodes.cs:9
static readonly OpCode Newarr
Definition OpCodes.cs:281
static readonly OpCode Ldarg
Definition OpCodes.cs:419
override string ToString()
StringBuilder Append(char value, int repeatCount)
static int Increment(ref int location)
Type? GetElementType()
bool IsByRef
Definition Type.cs:73

References System.Text.StringBuilder.Append(), System.array, System.Reflection.Emit.ILGenerator.BeginExceptionBlock(), System.Reflection.Emit.ILGenerator.BeginFinallyBlock(), System.Reflection.Emit.OpCodes.Box, System.Reflection.Emit.OpCodes.Call, System.Reflection.Emit.OpCodes.Callvirt, System.Dynamic.Utils.DelegateHelpers.ConvertToBoxableType(), System.Reflection.Emit.ILGenerator.DeclareLocal(), System.elementType, System.Reflection.Emit.ILGenerator.Emit(), System.Reflection.Emit.ILGenerator.EndExceptionBlock(), System.Dynamic.Utils.DelegateHelpers.GetCSharpThunk(), System.Type.GetElementType(), System.Reflection.Emit.DynamicMethod.GetILGenerator(), System.Threading.Interlocked.Increment(), System.Type.IsByRef, System.Reflection.Emit.OpCodes.Ldarg, System.Reflection.Emit.OpCodes.Ldarg_0, System.Reflection.Emit.OpCodes.Ldc_I4, System.Reflection.Emit.OpCodes.Ldelem_Ref, System.Reflection.Emit.OpCodes.Ldloc, System.Reflection.Emit.OpCodes.Ldobj, System.Reflection.MemberInfo.Name, System.Reflection.ParameterInfo.Name, System.Reflection.Emit.OpCodes.Newarr, System.Reflection.ParameterInfo.ParameterType, System.Reflection.Emit.OpCodes.Ret, System.Reflection.MethodInfo.ReturnType, System.Dynamic.Utils.DelegateHelpers.s_ArrayEmpty, System.Dynamic.Utils.DelegateHelpers.s_FuncInvoke, System.Dynamic.Utils.DelegateHelpers.s_thunks, System.Dynamic.Utils.DelegateHelpers.s_ThunksCreated, System.Reflection.Emit.OpCodes.Stelem_Ref, System.Reflection.Emit.OpCodes.Stloc, System.Reflection.Emit.OpCodes.Stobj, System.Text.StringBuilder.ToString(), System.type, System.Reflection.Emit.OpCodes.Unbox_Any, and System.value.

Referenced by System.Dynamic.Utils.DelegateHelpers.CreateObjectArrayDelegate().