Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CallInstruction.cs
Go to the documentation of this file.
5
7
8internal abstract class CallInstruction : Instruction
9{
11
12 public abstract int ArgumentCount { get; }
13
14 public override string InstructionName => "Call";
15
16 public override int ConsumedStack => ArgumentCount;
17
19 {
20 return Create(info, info.GetParametersCached());
21 }
22
23 public static CallInstruction Create(MethodInfo info, ParameterInfo[] parameters)
24 {
25 int num = parameters.Length;
26 if (!info.IsStatic)
27 {
28 num++;
29 }
30 if (info.DeclaringType != null && info.DeclaringType.IsArray && (info.Name == "Get" || info.Name == "Set"))
31 {
32 return GetArrayAccessor(info, num);
33 }
34 if (!info.IsStatic && info.DeclaringType.IsValueType)
35 {
36 return new MethodInfoCallInstruction(info, num);
37 }
38 if (num >= 5)
39 {
40 return new MethodInfoCallInstruction(info, num);
41 }
42 foreach (ParameterInfo parameterInfo in parameters)
43 {
44 if (parameterInfo.ParameterType.IsByRef)
45 {
46 return new MethodInfoCallInstruction(info, num);
47 }
48 }
50 if (s_cache.TryGetValue(info, out var value))
51 {
52 return value;
53 }
54 try
55 {
56 value = ((num >= 3) ? SlowCreate(info, parameters) : FastCreate(info, parameters));
57 }
59 {
60 if (!(ex.InnerException is NotSupportedException))
61 {
62 throw;
63 }
65 }
67 {
69 }
72 return value;
73 }
74
76 {
77 Type declaringType = info.DeclaringType;
78 bool flag = info.Name == "Get";
80 switch (declaringType.GetArrayRank())
81 {
82 case 1:
83 methodInfo = (flag ? typeof(Array).GetMethod("GetValue", new Type[1] { typeof(int) }) : typeof(CallInstruction).GetMethod("ArrayItemSetter1"));
84 break;
85 case 2:
86 methodInfo = (flag ? typeof(Array).GetMethod("GetValue", new Type[2]
87 {
88 typeof(int),
89 typeof(int)
90 }) : typeof(CallInstruction).GetMethod("ArrayItemSetter2"));
91 break;
92 case 3:
93 methodInfo = (flag ? typeof(Array).GetMethod("GetValue", new Type[3]
94 {
95 typeof(int),
96 typeof(int),
97 typeof(int)
98 }) : typeof(CallInstruction).GetMethod("ArrayItemSetter3"));
99 break;
100 }
101 if ((object)methodInfo == null)
102 {
104 }
105 return Create(methodInfo);
106 }
107
108 public static void ArrayItemSetter1(Array array, int index0, object value)
109 {
110 array.SetValue(value, index0);
111 }
112
113 public static void ArrayItemSetter2(Array array, int index0, int index1, object value)
114 {
115 array.SetValue(value, index0, index1);
116 }
117
118 public static void ArrayItemSetter3(Array array, int index0, int index1, int index2, object value)
119 {
120 array.SetValue(value, index0, index1, index2);
121 }
122
123 private static bool ShouldCache(MethodInfo info)
124 {
125 return true;
126 }
127
129 {
130 if (!target.IsStatic)
131 {
132 index--;
133 if (index < 0)
134 {
135 return target.DeclaringType;
136 }
137 }
138 if (index < pi.Length)
139 {
140 return pi[index].ParameterType;
141 }
142 if (target.ReturnType == typeof(void) || index > pi.Length)
143 {
144 return null;
145 }
146 return target.ReturnType;
147 }
148
149 private static bool IndexIsNotReturnType(int index, MethodInfo target, ParameterInfo[] pi)
150 {
151 if (pi.Length == index)
152 {
153 if (pi.Length == index)
154 {
155 return !target.IsStatic;
156 }
157 return false;
158 }
159 return true;
160 }
161
163 {
164 List<Type> list = new List<Type>();
165 if (!info.IsStatic)
166 {
167 list.Add(info.DeclaringType);
168 }
169 foreach (ParameterInfo parameterInfo in pis)
170 {
171 list.Add(parameterInfo.ParameterType);
172 }
173 if (info.ReturnType != typeof(void))
174 {
175 list.Add(info.ReturnType);
176 }
177 Type[] arrTypes = list.ToArray();
178 try
179 {
181 }
183 {
186 }
187 }
188
189 protected static bool TryGetLightLambdaTarget(object instance, [NotNullWhen(true)] out LightLambda lightLambda)
190 {
191 if (instance is Delegate { Target: Func<object[], object> target })
192 {
193 lightLambda = target.Target as LightLambda;
194 if (lightLambda != null)
195 {
196 return true;
197 }
198 }
199 lightLambda = null;
200 return false;
201 }
202
204 {
205 if (ProducedStack > 0)
206 {
207 return targetLambda.Run(args);
208 }
209 return targetLambda.RunVoid(args);
210 }
211
213 {
215 if (type == null)
216 {
217 return new ActionCallInstruction(target);
218 }
219 if (type.IsEnum)
220 {
221 return SlowCreate(target, pi);
222 }
223 switch (type.GetTypeCode())
224 {
225 case TypeCode.Object:
226 if (!(type != typeof(object)) || (!IndexIsNotReturnType(0, target, pi) && !type.IsValueType))
227 {
228 return FastCreate<object>(target, pi);
229 }
230 break;
231 case TypeCode.Int16:
232 return FastCreate<short>(target, pi);
233 case TypeCode.Int32:
234 return FastCreate<int>(target, pi);
235 case TypeCode.Int64:
236 return FastCreate<long>(target, pi);
237 case TypeCode.Boolean:
238 return FastCreate<bool>(target, pi);
239 case TypeCode.Char:
240 return FastCreate<char>(target, pi);
241 case TypeCode.Byte:
242 return FastCreate<byte>(target, pi);
243 case TypeCode.Decimal:
244 return FastCreate<decimal>(target, pi);
245 case TypeCode.DateTime:
246 return FastCreate<DateTime>(target, pi);
247 case TypeCode.Double:
248 return FastCreate<double>(target, pi);
249 case TypeCode.Single:
250 return FastCreate<float>(target, pi);
251 case TypeCode.UInt16:
252 return FastCreate<ushort>(target, pi);
253 case TypeCode.UInt32:
254 return FastCreate<uint>(target, pi);
255 case TypeCode.UInt64:
256 return FastCreate<ulong>(target, pi);
257 case TypeCode.String:
258 return FastCreate<string>(target, pi);
259 case TypeCode.SByte:
260 return FastCreate<sbyte>(target, pi);
261 }
262 return SlowCreate(target, pi);
263 }
264
266 {
268 if (type == null)
269 {
270 if (target.ReturnType == typeof(void))
271 {
272 return new ActionCallInstruction<T0>(target);
273 }
274 return new FuncCallInstruction<T0>(target);
275 }
276 if (type.IsEnum)
277 {
278 return SlowCreate(target, pi);
279 }
280 switch (type.GetTypeCode())
281 {
282 case TypeCode.Object:
283 if (!(type != typeof(object)) || (!IndexIsNotReturnType(1, target, pi) && !type.IsValueType))
284 {
285 return FastCreate<T0, object>(target, pi);
286 }
287 break;
288 case TypeCode.Int16:
289 return FastCreate<T0, short>(target, pi);
290 case TypeCode.Int32:
291 return FastCreate<T0, int>(target, pi);
292 case TypeCode.Int64:
293 return FastCreate<T0, long>(target, pi);
294 case TypeCode.Boolean:
295 return FastCreate<T0, bool>(target, pi);
296 case TypeCode.Char:
297 return FastCreate<T0, char>(target, pi);
298 case TypeCode.Byte:
299 return FastCreate<T0, byte>(target, pi);
300 case TypeCode.Decimal:
301 return FastCreate<T0, decimal>(target, pi);
302 case TypeCode.DateTime:
303 return FastCreate<T0, DateTime>(target, pi);
304 case TypeCode.Double:
305 return FastCreate<T0, double>(target, pi);
306 case TypeCode.Single:
307 return FastCreate<T0, float>(target, pi);
308 case TypeCode.UInt16:
309 return FastCreate<T0, ushort>(target, pi);
310 case TypeCode.UInt32:
311 return FastCreate<T0, uint>(target, pi);
312 case TypeCode.UInt64:
313 return FastCreate<T0, ulong>(target, pi);
314 case TypeCode.String:
315 return FastCreate<T0, string>(target, pi);
316 case TypeCode.SByte:
317 return FastCreate<T0, sbyte>(target, pi);
318 }
319 return SlowCreate(target, pi);
320 }
321
323 {
325 if (type == null)
326 {
327 if (target.ReturnType == typeof(void))
328 {
329 return new ActionCallInstruction<T0, T1>(target);
330 }
331 return new FuncCallInstruction<T0, T1>(target);
332 }
333 if (type.IsEnum)
334 {
335 return SlowCreate(target, pi);
336 }
337 switch (type.GetTypeCode())
338 {
339 case TypeCode.Object:
340 if (!type.IsValueType)
341 {
342 return new FuncCallInstruction<T0, T1, object>(target);
343 }
344 break;
345 case TypeCode.Int16:
346 return new FuncCallInstruction<T0, T1, short>(target);
347 case TypeCode.Int32:
348 return new FuncCallInstruction<T0, T1, int>(target);
349 case TypeCode.Int64:
350 return new FuncCallInstruction<T0, T1, long>(target);
351 case TypeCode.Boolean:
352 return new FuncCallInstruction<T0, T1, bool>(target);
353 case TypeCode.Char:
354 return new FuncCallInstruction<T0, T1, char>(target);
355 case TypeCode.Byte:
356 return new FuncCallInstruction<T0, T1, byte>(target);
357 case TypeCode.Decimal:
358 return new FuncCallInstruction<T0, T1, decimal>(target);
359 case TypeCode.DateTime:
360 return new FuncCallInstruction<T0, T1, DateTime>(target);
361 case TypeCode.Double:
362 return new FuncCallInstruction<T0, T1, double>(target);
363 case TypeCode.Single:
364 return new FuncCallInstruction<T0, T1, float>(target);
365 case TypeCode.UInt16:
366 return new FuncCallInstruction<T0, T1, ushort>(target);
367 case TypeCode.UInt32:
368 return new FuncCallInstruction<T0, T1, uint>(target);
369 case TypeCode.UInt64:
370 return new FuncCallInstruction<T0, T1, ulong>(target);
371 case TypeCode.String:
372 return new FuncCallInstruction<T0, T1, string>(target);
373 case TypeCode.SByte:
374 return new FuncCallInstruction<T0, T1, sbyte>(target);
375 }
376 return SlowCreate(target, pi);
377 }
378
381 {
382 if (info.ReturnType == typeof(void))
383 {
384 return arrTypes.Length switch
385 {
387 1 => typeof(ActionCallInstruction<>).MakeGenericType(arrTypes),
388 2 => typeof(ActionCallInstruction<, >).MakeGenericType(arrTypes),
389 3 => typeof(ActionCallInstruction<, , >).MakeGenericType(arrTypes),
390 4 => typeof(ActionCallInstruction<, , , >).MakeGenericType(arrTypes),
391 _ => throw new InvalidOperationException(),
392 };
393 }
394 return arrTypes.Length switch
395 {
396 1 => typeof(FuncCallInstruction<>).MakeGenericType(arrTypes),
397 2 => typeof(FuncCallInstruction<, >).MakeGenericType(arrTypes),
398 3 => typeof(FuncCallInstruction<, , >).MakeGenericType(arrTypes),
399 4 => typeof(FuncCallInstruction<, , , >).MakeGenericType(arrTypes),
400 5 => typeof(FuncCallInstruction<, , , , >).MakeGenericType(arrTypes),
401 _ => throw new InvalidOperationException(),
402 };
403 }
404}
static ? object CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors|DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture)
Definition Activator.cs:17
static Type GetHelperType(MethodInfo info, Type[] arrTypes)
static CallInstruction FastCreate< T0 >(MethodInfo target, ParameterInfo[] pi)
static CallInstruction SlowCreate(MethodInfo info, ParameterInfo[] pis)
static Type TryGetParameterOrReturnType(MethodInfo target, ParameterInfo[] pi, int index)
object InterpretLambdaInvoke(LightLambda targetLambda, object[] args)
static CallInstruction Create(MethodInfo info, ParameterInfo[] parameters)
static void ArrayItemSetter2(Array array, int index0, int index1, object value)
static bool IndexIsNotReturnType(int index, MethodInfo target, ParameterInfo[] pi)
static CallInstruction FastCreate(MethodInfo target, ParameterInfo[] pi)
static CallInstruction FastCreate< T0, T1 >(MethodInfo target, ParameterInfo[] pi)
static bool TryGetLightLambdaTarget(object instance, [NotNullWhen(true)] out LightLambda lightLambda)
static void ArrayItemSetter1(Array array, int index0, object value)
static readonly CacheDict< MethodInfo, CallInstruction > s_cache
static CallInstruction GetArrayAccessor(MethodInfo info, int argumentCount)
static CallInstruction Create(MethodInfo info)
static void ArrayItemSetter3(Array array, int index0, int index1, int index2, object value)
static void UnwrapAndRethrow(TargetInvocationException exception)
TypeCode
Definition TypeCode.cs:4