Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
InstructionList.cs
Go to the documentation of this file.
6
8
9[DebuggerTypeProxy(typeof(DebugView))]
10internal sealed class InstructionList
11{
12 internal sealed class DebugView
13 {
14 [DebuggerDisplay("{GetValue(),nq}", Name = "{GetName(),nq}", Type = "{GetDisplayType(), nq}")]
15 internal readonly struct InstructionView
16 {
17 private readonly int _index;
18
19 private readonly int _stackDepth;
20
21 private readonly int _continuationsDepth;
22
23 private readonly string _name;
24
25 private readonly Instruction _instruction;
26
27 internal string GetName()
28 {
29 return _index + ((_continuationsDepth == 0) ? "" : (" C(" + _continuationsDepth + ")")) + ((_stackDepth == 0) ? "" : (" S(" + _stackDepth + ")"));
30 }
31
32 internal string GetValue()
33 {
34 return _name;
35 }
36
37 internal string GetDisplayType()
38 {
39 return _instruction.ContinuationsBalance + "/" + _instruction.StackBalance;
40 }
41
50 }
51
52 private readonly InstructionList _list;
53
56
62
64 {
65 return GetInstructionViews(_list._instructions, _list._objects, (int index) => _list._labels[index].TargetIndex, null);
66 }
67
69 {
71 int num = 0;
72 int num2 = 0;
73 int num3 = 0;
75 bool flag = enumerator.MoveNext();
76 int i = 0;
77 for (int count = instructions.Count; i < count; i++)
78 {
80 object cookie = null;
81 while (flag && enumerator.Current.Key == i)
82 {
83 cookie = enumerator.Current.Value;
84 flag = enumerator.MoveNext();
85 }
86 int stackBalance = instruction.StackBalance;
87 int continuationsBalance = instruction.ContinuationsBalance;
88 string name = instruction.ToDebugString(i, cookie, labelIndexer, objects);
90 num++;
93 }
94 return list.ToArray();
95 }
96 }
97
99
101
103
104 private int _maxStackDepth;
105
107
109
111
113
114 private static Instruction s_null;
115
116 private static Instruction s_true;
117
118 private static Instruction s_false;
119
120 private static Instruction[] s_Ints;
121
123
124 private static Instruction[] s_loadLocal;
125
127
129
131
132 private static Instruction[] s_assignLocal;
133
134 private static Instruction[] s_storeLocal;
135
137
139
141
143
144 private static readonly RuntimeLabel[] s_emptyRuntimeLabels = new RuntimeLabel[1]
145 {
146 new RuntimeLabel(int.MaxValue, 0, 0)
147 };
148
149 public int Count => _instructions.Count;
150
152
154
160
176
177 public void UnEmit()
178 {
179 Instruction instruction = _instructions[_instructions.Count - 1];
180 _instructions.RemoveAt(_instructions.Count - 1);
181 _currentContinuationsDepth -= instruction.ProducedContinuations;
182 _currentContinuationsDepth += instruction.ConsumedContinuations;
183 _currentStackDepth -= instruction.ProducedStack;
184 _currentStackDepth += instruction.ConsumedStack;
185 }
186
188 {
189 return _instructions[index];
190 }
191
196
197 public void EmitLoad(object value)
198 {
199 EmitLoad(value, null);
200 }
201
202 public void EmitLoad(bool value)
203 {
204 if (value)
205 {
207 }
208 else
209 {
211 }
212 }
213
214 public void EmitLoad(object value, Type type)
215 {
216 if (value == null)
217 {
218 Emit(s_null ?? (s_null = new LoadObjectInstruction(null)));
219 return;
220 }
221 if (type == null || type.IsValueType)
222 {
223 if (value is bool)
224 {
225 EmitLoad((bool)value);
226 return;
227 }
228 if (value is int num && num >= -100 && num <= 100)
229 {
230 if (s_Ints == null)
231 {
232 s_Ints = new Instruction[201];
233 }
234 int num2 = num - -100;
235 Emit(s_Ints[num2] ?? (s_Ints[num2] = new LoadObjectInstruction(value)));
236 return;
237 }
238 }
239 if (_objects == null)
240 {
241 _objects = new List<object>();
242 if (s_loadObjectCached == null)
243 {
245 }
246 }
247 if (_objects.Count < s_loadObjectCached.Length)
248 {
249 uint count = (uint)_objects.Count;
252 }
253 else
254 {
255 Emit(new LoadObjectInstruction(value));
256 }
257 }
258
259 public void EmitDup()
260 {
262 }
263
264 public void EmitPop()
265 {
267 }
268
269 internal void SwitchToBoxed(int index, int instructionIndex)
270 {
272 {
273 Instruction instruction = boxableInstruction.BoxIfIndexMatches(index);
274 if (instruction != null)
275 {
277 }
278 }
279 }
280
281 public void EmitLoadLocal(int index)
282 {
283 if (s_loadLocal == null)
284 {
285 s_loadLocal = new Instruction[64];
286 }
287 if (index < s_loadLocal.Length)
288 {
290 }
291 else
292 {
293 Emit(new LoadLocalInstruction(index));
294 }
295 }
296
297 public void EmitLoadLocalBoxed(int index)
298 {
299 Emit(LoadLocalBoxed(index));
300 }
301
302 internal static Instruction LoadLocalBoxed(int index)
303 {
304 if (s_loadLocalBoxed == null)
305 {
307 }
308 if (index < s_loadLocalBoxed.Length)
309 {
311 }
313 }
314
316 {
317 if (s_loadLocalFromClosure == null)
318 {
320 }
321 if (index < s_loadLocalFromClosure.Length)
322 {
324 }
325 else
326 {
328 }
329 }
330
346
347 public void EmitAssignLocal(int index)
348 {
349 if (s_assignLocal == null)
350 {
351 s_assignLocal = new Instruction[64];
352 }
353 if (index < s_assignLocal.Length)
354 {
356 }
357 else
358 {
359 Emit(new AssignLocalInstruction(index));
360 }
361 }
362
363 public void EmitStoreLocal(int index)
364 {
365 if (s_storeLocal == null)
366 {
367 s_storeLocal = new Instruction[64];
368 }
369 if (index < s_storeLocal.Length)
370 {
372 }
373 else
374 {
375 Emit(new StoreLocalInstruction(index));
376 }
377 }
378
380 {
381 Emit(AssignLocalBoxed(index));
382 }
383
384 internal static Instruction AssignLocalBoxed(int index)
385 {
386 if (s_assignLocalBoxed == null)
387 {
389 }
390 if (index < s_assignLocalBoxed.Length)
391 {
393 }
395 }
396
397 public void EmitStoreLocalBoxed(int index)
398 {
399 Emit(StoreLocalBoxed(index));
400 }
401
402 internal static Instruction StoreLocalBoxed(int index)
403 {
404 if (s_storeLocalBoxed == null)
405 {
407 }
408 if (index < s_storeLocalBoxed.Length)
409 {
411 }
413 }
414
416 {
417 if (s_assignLocalToClosure == null)
418 {
420 }
421 if (index < s_assignLocalToClosure.Length)
422 {
424 }
425 else
426 {
428 }
429 }
430
432 {
434 EmitPop();
435 }
436
438 {
440 if (primitiveDefaultValue != null)
441 {
443 }
444 else if (type.IsValueType)
445 {
447 }
448 else
449 {
450 Emit(InitReference(index));
451 }
452 }
453
455 {
456 Emit(Parameter(index));
457 }
458
459 internal static Instruction Parameter(int index)
460 {
462 }
463
464 internal static Instruction ParameterBox(int index)
465 {
467 }
468
469 internal static Instruction InitReference(int index)
470 {
472 }
473
475 {
477 }
478
480 {
482 }
483
484 public void EmitGetArrayItem()
485 {
487 }
488
489 public void EmitSetArrayItem()
490 {
492 }
493
495 {
497 }
498
500 {
502 }
503
508
509 public void EmitAdd(Type type, bool @checked)
510 {
512 }
513
514 public void EmitSub(Type type, bool @checked)
515 {
517 }
518
519 public void EmitMul(Type type, bool @checked)
520 {
522 }
523
524 public void EmitDiv(Type type)
525 {
527 }
528
529 public void EmitModulo(Type type)
530 {
532 }
533
535 {
537 }
538
539 public void EmitAnd(Type type)
540 {
542 }
543
544 public void EmitOr(Type type)
545 {
547 }
548
550 {
552 }
553
555 {
557 }
558
559 public void EmitEqual(Type type, bool liftedToNull = false)
560 {
562 }
563
564 public void EmitNotEqual(Type type, bool liftedToNull = false)
565 {
567 }
568
570 {
572 }
573
578
583
588
593
598
603
604 public void EmitCast(Type toType)
605 {
607 }
608
610 {
611 Emit(new CastToEnumInstruction(toType));
612 }
613
618
619 public void EmitNot(Type type)
620 {
622 }
623
625 {
626 Emit(new DefaultValueInstruction(type));
627 }
628
630 {
631 Emit(new NewInstruction(constructorInfo, parameters.Length));
632 }
633
635 {
636 Emit(new ByRefNewInstruction(constructorInfo, parameters.Length, updaters));
637 }
638
643
644 public void EmitTypeEquals()
645 {
647 }
648
649 public void EmitArrayLength()
650 {
652 }
653
654 public void EmitNegate(Type type)
655 {
657 }
658
660 {
662 }
663
665 {
667 }
668
670 {
672 }
673
674 public void EmitTypeIs(Type type)
675 {
676 Emit(new TypeIsInstruction(type));
677 }
678
679 public void EmitTypeAs(Type type)
680 {
681 Emit(new TypeAsInstruction(type));
682 }
683
685 {
686 Emit(GetLoadField(field));
687 }
688
690 {
692 {
693 if (!s_loadFields.TryGetValue(field, out var value))
694 {
697 }
698 return value;
699 }
700 }
701
703 {
704 if (field.IsStatic)
705 {
707 }
708 else
709 {
710 Emit(new StoreFieldInstruction(field));
711 }
712 }
713
715 {
716 EmitCall(method, method.GetParametersCached());
717 }
718
719 public void EmitCall(MethodInfo method, ParameterInfo[] parameters)
720 {
721 Emit(CallInstruction.Create(method, parameters));
722 }
723
725 {
726 Emit(new ByRefMethodInfoCallInstruction(method, method.IsStatic ? parameters.Length : (parameters.Length + 1), byrefArgs));
727 }
728
730 {
731 Emit(NullableMethodCallInstruction.Create(method.Name, parameters.Length, method));
732 }
733
735 {
736 if (_runtimeLabelCount == 0)
737 {
739 }
741 foreach (BranchLabel label in _labels)
742 {
743 if (label.HasRuntimeLabel)
744 {
745 array[label.LabelIndex] = label.ToRuntimeLabel();
746 }
747 }
748 array[^1] = new RuntimeLabel(int.MaxValue, 0, 0);
749 return array;
750 }
751
753 {
754 if (_labels == null)
755 {
757 }
760 return branchLabel;
761 }
762
767
769 {
770 if (label.HasRuntimeLabel)
771 {
772 return label.LabelIndex;
773 }
774 label.LabelIndex = _runtimeLabelCount;
776 return label.LabelIndex;
777 }
778
779 public int MarkRuntimeLabel()
780 {
783 return EnsureLabelIndex(label);
784 }
785
787 {
788 label.Mark(this);
789 }
790
791 public void EmitGoto(BranchLabel label, bool hasResult, bool hasValue, bool labelTargetGetsValue)
792 {
794 }
795
797 {
798 Emit(instruction);
799 label.AddBranch(this, Count - 1);
800 }
801
803 {
805 }
806
807 public void EmitBranch(BranchLabel label, bool hasResult, bool hasValue)
808 {
810 }
811
816
821
826
827 public void EmitThrow()
828 {
830 }
831
832 public void EmitThrowVoid()
833 {
835 }
836
837 public void EmitRethrow()
838 {
840 }
841
842 public void EmitRethrowVoid()
843 {
845 }
846
851
856
863
868
869 public void EmitLeaveFinally()
870 {
872 }
873
878
879 public void EmitLeaveFault()
880 {
882 }
883
888
893
898
903
908
913
918}
void Add(TKey key, TValue value)
static void RequiresNotNull(object value, string paramName)
static CallInstruction Create(MethodInfo info)
static EnterFaultInstruction Create(int labelIndex)
static EnterFinallyInstruction Create(int labelIndex)
static EnterTryCatchFinallyInstruction CreateTryFinally(int labelIndex)
static Instruction Create(Type type, bool liftedToNull)
static GotoInstruction Create(int labelIndex, bool hasResult, bool hasValue, bool labelTargetGetsValue)
static Instruction Create(Type type, bool liftedToNull=false)
static Instruction Create(Type type, bool liftedToNull=false)
static InstructionView[] GetInstructionViews(IReadOnlyList< Instruction > instructions, IReadOnlyList< object > objects, Func< int, int > labelIndexer, IReadOnlyList< KeyValuePair< int, object > > debugCookies)
InstructionView[] GetInstructionViews(bool includeDebugCookies=false)
void EmitIntSwitch< T >(Dictionary< T, int > cases)
void EmitGreaterThanOrEqual(Type type, bool liftedToNull)
void SwitchToBoxed(int index, int instructionIndex)
EnterTryFaultInstruction EmitEnterTryFault(BranchLabel tryEnd)
void EmitNewArrayBounds(Type elementType, int rank)
void EmitNew(ConstructorInfo constructorInfo, ParameterInfo[] parameters)
void EmitEnterTryFinally(BranchLabel finallyStartLabel)
void EmitStringSwitch(Dictionary< string, int > cases, StrongBox< int > nullCase)
void EmitGoto(BranchLabel label, bool hasResult, bool hasValue, bool labelTargetGetsValue)
void EmitEqual(Type type, bool liftedToNull=false)
void EmitCreateDelegate(LightDelegateCreator creator)
void EmitBranch(BranchLabel label, bool hasResult, bool hasValue)
void EmitLessThanOrEqual(Type type, bool liftedToNull)
void EmitByRefCall(MethodInfo method, ParameterInfo[] parameters, ByRefUpdater[] byrefArgs)
void EmitNewArrayInit(Type elementType, int elementCount)
void EmitLessThan(Type type, bool liftedToNull)
static readonly Dictionary< FieldInfo, Instruction > s_loadFields
void EmitNullableCall(MethodInfo method, ParameterInfo[] parameters)
void EmitNumericConvertChecked(TypeCode from, TypeCode to, bool isLiftedToNull)
void EmitLeaveExceptionHandler(bool hasValue, BranchLabel tryExpressionEndLabel)
void EmitCall(MethodInfo method, ParameterInfo[] parameters)
void EmitNotEqual(Type type, bool liftedToNull=false)
void EmitConvertToUnderlying(TypeCode to, bool isLiftedToNull)
void EmitGreaterThan(Type type, bool liftedToNull)
void EmitEnterFinally(BranchLabel finallyStartLabel)
void EmitBranch(OffsetInstruction instruction, BranchLabel label)
void EmitNumericConvertUnchecked(TypeCode from, TypeCode to, bool isLiftedToNull)
void EmitByRefNew(ConstructorInfo constructorInfo, ParameterInfo[] parameters, ByRefUpdater[] updaters)
void EmitEnterFault(BranchLabel faultStartLabel)
static LeaveExceptionHandlerInstruction Create(int labelIndex, bool hasValue)
static Instruction Create(Type type, bool liftedToNull=false)
static Instruction Create(Type type, bool liftedToNull=false)
static Instruction Create(Type type, bool liftedToNull)
static Instruction Create(string method, int argCount, MethodInfo mi)
static readonly object BoxedTrue
Definition Utils.cs:10
static readonly object BoxedFalse
Definition Utils.cs:8
TypeCode
Definition TypeCode.cs:4
InstructionView(Instruction instruction, string name, int index, int stackDepth, int continuationsDepth)