Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
StackSpiller.cs
Go to the documentation of this file.
7
9
10internal sealed class StackSpiller
11{
12 private abstract class BindingRewriter
13 {
14 protected readonly MemberBinding _binding;
15
16 protected readonly StackSpiller _spiller;
17
19
20 internal RewriteAction Action => _action;
21
27
28 internal abstract MemberBinding AsBinding();
29
30 internal abstract Expression AsExpression(Expression target);
31
33 {
34 switch (binding.BindingType)
35 {
36 case MemberBindingType.Assignment:
37 {
39 return new MemberAssignmentRewriter(binding4, spiller, stack);
40 }
41 case MemberBindingType.ListBinding:
42 {
44 return new ListBindingRewriter(binding3, spiller, stack);
45 }
46 case MemberBindingType.MemberBinding:
47 {
50 }
51 default:
52 throw Error.UnhandledBinding();
53 }
54 }
55
56 protected void RequireNoValueProperty()
57 {
58 if (_binding.Member is PropertyInfo propertyInfo && propertyInfo.PropertyType.IsValueType)
59 {
61 }
62 }
63 }
64
66 {
68
70
84
85 internal override MemberBinding AsBinding()
86 {
87 switch (_action)
88 {
89 case RewriteAction.None:
90 return _binding;
91 case RewriteAction.Copy:
92 {
93 int count = _bindings.Count;
95 for (int i = 0; i < count; i++)
96 {
98 }
100 }
101 default:
103 }
104 }
105
106 internal override Expression AsExpression(Expression target)
107 {
111 int count = _bindings.Count;
112 Expression[] array = new Expression[count + 2];
114 for (int i = 0; i < count; i++)
115 {
117 array[i + 1] = bindingRewriter.AsExpression(expression2);
118 }
119 if (expression2.Type.IsValueType)
120 {
122 }
123 else
124 {
125 array[count + 1] = Utils.Empty;
126 }
127 return MakeBlock(array);
128 }
129 }
130
132 {
134
135 private readonly ChildRewriter[] _childRewriters;
136
139 {
140 _inits = binding.Initializers;
141 int count = _inits.Count;
143 for (int i = 0; i < count; i++)
144 {
147 childRewriter.Add(elementInit.Arguments);
148 _action |= childRewriter.Action;
150 }
151 }
152
153 internal override MemberBinding AsBinding()
154 {
155 switch (_action)
156 {
157 case RewriteAction.None:
158 return _binding;
159 case RewriteAction.Copy:
160 {
161 int count = _inits.Count;
163 for (int i = 0; i < count; i++)
164 {
166 if (childRewriter.Action == RewriteAction.None)
167 {
168 array[i] = _inits[i];
169 }
170 else
171 {
172 array[i] = new ElementInit(_inits[i].AddMethod, new TrueReadOnlyCollection<Expression>(childRewriter[0, -1]));
173 }
174 }
176 }
177 default:
179 }
180 }
181
182 internal override Expression AsExpression(Expression target)
183 {
187 int count = _inits.Count;
188 Expression[] array = new Expression[count + 2];
190 for (int i = 0; i < count; i++)
191 {
193 array[i + 1] = childRewriter.Finish(new InstanceMethodCallExpressionN(_inits[i].AddMethod, expression2, childRewriter[0, -1])).Node;
194 }
195 if (expression2.Type.IsValueType)
196 {
198 }
199 else
200 {
201 array[count + 1] = Utils.Empty;
202 }
203 return MakeBlock(array);
204 }
205 }
206
208 {
209 private readonly Expression _rhs;
210
213 {
214 Result result = spiller.RewriteExpression(binding.Expression, stack);
215 _action = result.Action;
216 _rhs = result.Node;
217 }
218
219 internal override MemberBinding AsBinding()
220 {
221 return _action switch
222 {
223 RewriteAction.None => _binding,
224 RewriteAction.Copy => new MemberAssignment(_binding.Member, _rhs),
225 _ => throw ContractUtils.Unreachable,
226 };
227 }
228
235 }
236
237 private sealed class ChildRewriter
238 {
239 private readonly StackSpiller _self;
240
241 private readonly Expression[] _expressions;
242
243 private int _expressionsCount;
244
245 private int _lastSpillIndex;
246
248
250
251 private Stack _stack;
252
253 private bool _done;
254
255 private bool[] _byRefs;
256
257 internal bool Rewrite => _action != RewriteAction.None;
258
259 internal RewriteAction Action => _action;
260
261 internal Expression this[int index]
262 {
263 get
264 {
265 EnsureDone();
266 if (index < 0)
267 {
268 index += _expressions.Length;
269 }
270 return _expressions[index];
271 }
272 }
273
274 internal Expression[] this[int first, int last]
275 {
276 get
277 {
278 EnsureDone();
279 if (last < 0)
280 {
281 last += _expressions.Length;
282 }
283 int num = last - first + 1;
284 ContractUtils.RequiresArrayRange(_expressions, first, num, "first", "last");
285 if (num == _expressions.Length)
286 {
287 return _expressions;
288 }
289 Expression[] array = new Expression[num];
290 Array.Copy(_expressions, first, array, 0, num);
291 return array;
292 }
293 }
294
295 internal ChildRewriter(StackSpiller self, Stack stack, int count)
296 {
297 _self = self;
298 _stack = stack;
300 }
301
302 internal void Add(Expression expression)
303 {
304 if (expression == null)
305 {
307 return;
308 }
310 _action |= result.Action;
311 _stack = Stack.NonEmpty;
312 if (result.Action == RewriteAction.SpillStack)
313 {
315 }
317 }
318
320 {
321 int i = 0;
322 for (int count = expressions.Count; i < count; i++)
323 {
324 Add(expressions[i]);
325 }
326 }
327
329 {
330 int i = 0;
331 for (int argumentCount = expressions.ArgumentCount; i < argumentCount; i++)
332 {
333 Add(expressions.GetArgument(i));
334 }
335 }
336
337 private void EnsureDone()
338 {
339 if (_done)
340 {
341 return;
342 }
343 _done = true;
344 if (_action != RewriteAction.SpillStack)
345 {
346 return;
347 }
349 int num = _lastSpillIndex + 1;
351 for (int i = 0; i < num; i++)
352 {
355 {
356 int num2 = i;
357 StackSpiller self = _self;
358 bool[] byRefs = _byRefs;
359 expressions[num2] = self.ToTemp(expression, out var save, byRefs != null && byRefs[i]);
360 list.Add(save);
361 }
362 }
363 list.Capacity = list.Count + 1;
364 _comma = list;
365 }
366
368 {
369 if (expression == null)
370 {
371 return false;
372 }
373 switch (expression.NodeType)
374 {
375 case ExpressionType.Constant:
376 case ExpressionType.Default:
377 return false;
378 case ExpressionType.RuntimeVariables:
379 return false;
380 case ExpressionType.MemberAccess:
381 {
383 FieldInfo fieldInfo = memberExpression.Member as FieldInfo;
384 if (fieldInfo != null)
385 {
386 if (fieldInfo.IsLiteral)
387 {
388 return false;
389 }
390 if (fieldInfo.IsInitOnly && fieldInfo.IsStatic)
391 {
392 return false;
393 }
394 }
395 break;
396 }
397 }
398 return true;
399 }
400
401 internal void MarkRefInstance(Expression expr)
402 {
403 if (IsRefInstance(expr))
404 {
405 MarkRef(0);
406 }
407 }
408
410 {
411 ParameterInfo[] parametersCached = method.GetParametersCached();
412 int i = 0;
413 for (int num = parametersCached.Length; i < num; i++)
414 {
415 if (parametersCached[i].ParameterType.IsByRef)
416 {
417 MarkRef(startIndex + i);
418 }
419 }
420 }
421
422 private void MarkRef(int index)
423 {
424 if (_byRefs == null)
425 {
426 _byRefs = new bool[_expressions.Length];
427 }
428 _byRefs[index] = true;
429 }
430
432 {
433 EnsureDone();
434 if (_action == RewriteAction.SpillStack)
435 {
438 }
439 return new Result(_action, expression);
440 }
441 }
442
443 private enum Stack
444 {
445 Empty,
447 }
448
449 [Flags]
450 private enum RewriteAction
451 {
452 None = 0,
453 Copy = 1,
454 SpillStack = 3
455 }
456
457 private readonly struct Result
458 {
459 internal readonly RewriteAction Action;
460
461 internal readonly Expression Node;
462
464 {
465 Action = action;
466 Node = node;
467 }
468 }
469
470 private sealed class TempMaker
471 {
472 private int _temp;
473
475
477
479
480
482 {
484 if (_freeTemps != null)
485 {
486 for (int num = _freeTemps.Count - 1; num >= 0; num--)
487 {
489 if (parameterExpression.Type == type)
490 {
491 _freeTemps.RemoveAt(num);
493 }
494 }
495 }
499 }
500
502 {
503 if (_usedTemps == null)
504 {
506 }
507 _usedTemps.Push(temp);
508 return temp;
509 }
510
512 {
513 if (_freeTemps == null)
514 {
516 }
518 }
519
520 internal int Mark()
521 {
522 return _usedTemps?.Count ?? 0;
523 }
524
525 internal void Free(int mark)
526 {
527 if (_usedTemps != null)
528 {
529 while (mark < _usedTemps.Count)
530 {
531 FreeTemp(_usedTemps.Pop());
532 }
533 }
534 }
535 }
536
537 private readonly Stack _startingStack;
538
540
541 private readonly StackGuard _guard = new StackGuard();
542
543 private readonly TempMaker _tm = new TempMaker();
544
546 {
547 return lambda.Accept(new StackSpiller(Stack.Empty));
548 }
549
550 private StackSpiller(Stack stack)
551 {
552 _startingStack = stack;
553 }
554
556 {
558 _lambdaRewrite = result.Action;
559 if (result.Action != 0)
560 {
561 Expression expression = result.Node;
562 if (_tm.Temps.Count > 0)
563 {
565 }
566 return Expression<T>.Create(expression, lambda.Name, lambda.TailCall, new ParameterList(lambda));
567 }
568 return lambda;
569 }
570
572 {
573 int mark = Mark();
574 Result result = RewriteExpression(expression, stack);
575 Free(mark);
576 return result;
577 }
578
580 {
582 ChildRewriter childRewriter = new ChildRewriter(this, Stack.NonEmpty, dynamicExpression.ArgumentCount);
583 childRewriter.AddArguments(dynamicExpression);
584 if (childRewriter.Action == RewriteAction.SpillStack)
585 {
586 RequireNoRefArgs(dynamicExpression.DelegateType.GetInvokeMethod());
587 }
588 return childRewriter.Finish(childRewriter.Rewrite ? dynamicExpression.Rewrite(childRewriter[0, -1]) : expr);
589 }
590
592 {
594 ChildRewriter childRewriter = new ChildRewriter(this, stack, 2 + indexExpression.ArgumentCount);
596 childRewriter.AddArguments(indexExpression);
597 childRewriter.Add(node.Right);
598 if (childRewriter.Action == RewriteAction.SpillStack)
599 {
600 childRewriter.MarkRefInstance(indexExpression.Object);
601 }
602 if (childRewriter.Rewrite)
603 {
605 }
606 return childRewriter.Finish(node);
607 }
608
610 {
612 Result result = RewriteExpression(binaryExpression.Left, stack);
615 RewriteAction rewriteAction = result.Action | result2.Action | result3.Action;
616 if (rewriteAction != 0)
617 {
619 }
620 return new Result(rewriteAction, expr);
621 }
622
624 {
625 Result result = RewriteExpression(expr.Reduce(), stack);
626 return new Result(result.Action | RewriteAction.Copy, result.Node);
627 }
628
642
644 {
645 Result result = RewriteExpression(node.Right, stack);
646 if (result.Action != 0)
647 {
648 node = new AssignBinaryExpression(node.Left, result.Node);
649 }
650 return new Result(result.Action, node);
651 }
652
654 {
656 return binaryExpression.Left.NodeType switch
657 {
658 ExpressionType.Index => RewriteIndexAssignment(binaryExpression, stack),
659 ExpressionType.MemberAccess => RewriteMemberAssignment(binaryExpression, stack),
660 ExpressionType.Parameter => RewriteVariableAssignment(binaryExpression, stack),
661 ExpressionType.Extension => RewriteExtensionAssignment(binaryExpression, stack),
662 _ => throw Error.InvalidLvalue(binaryExpression.Left.NodeType),
663 };
664 }
665
667 {
668 node = new AssignBinaryExpression(node.Left.ReduceExtensions(), node.Right);
670 return new Result(result.Action | RewriteAction.Copy, result.Node);
671 }
672
674 {
678 return new Result(action, expr);
679 }
680
682 {
684 Result result = RewriteExpression(conditionalExpression.Test, stack);
687 RewriteAction rewriteAction = result.Action | result2.Action | result3.Action;
688 if (rewriteAction != 0)
689 {
690 expr = ConditionalExpression.Make(result.Node, result2.Node, result3.Node, conditionalExpression.Type);
691 }
692 return new Result(rewriteAction, expr);
693 }
694
696 {
698 ChildRewriter childRewriter = new ChildRewriter(this, stack, 2);
700 childRewriter.Add(node.Right);
701 if (childRewriter.Action == RewriteAction.SpillStack)
702 {
703 childRewriter.MarkRefInstance(memberExpression.Expression);
704 }
705 if (childRewriter.Rewrite)
706 {
708 }
709 return new Result(RewriteAction.None, node);
710 }
711
713 {
715 Result result = RewriteExpression(memberExpression.Expression, stack);
716 if (result.Action != 0)
717 {
718 if (result.Action == RewriteAction.SpillStack && memberExpression.Member is PropertyInfo)
719 {
721 }
722 expr = MemberExpression.Make(result.Node, memberExpression.Member);
723 }
724 return new Result(result.Action, expr);
725 }
726
728 {
730 ChildRewriter childRewriter = new ChildRewriter(this, stack, indexExpression.ArgumentCount + 1);
732 childRewriter.AddArguments(indexExpression);
733 if (childRewriter.Action == RewriteAction.SpillStack)
734 {
735 childRewriter.MarkRefInstance(indexExpression.Object);
736 }
737 if (childRewriter.Rewrite)
738 {
739 expr = new IndexExpression(childRewriter[0], indexExpression.Indexer, childRewriter[1, -1]);
740 }
741 return childRewriter.Finish(expr);
742 }
743
745 {
747 ChildRewriter childRewriter = new ChildRewriter(this, stack, methodCallExpression.ArgumentCount + 1);
750 if (childRewriter.Action == RewriteAction.SpillStack)
751 {
752 childRewriter.MarkRefInstance(methodCallExpression.Object);
753 childRewriter.MarkRefArgs(methodCallExpression.Method, 1);
754 }
755 if (childRewriter.Rewrite)
756 {
757 expr = ((methodCallExpression.Object == null) ? ((MethodCallExpression)new MethodCallExpressionN(methodCallExpression.Method, childRewriter[1, -1])) : ((MethodCallExpression)new InstanceMethodCallExpressionN(methodCallExpression.Method, childRewriter[0], childRewriter[1, -1])));
758 }
759 return childRewriter.Finish(expr);
760 }
761
763 {
765 if (newArrayExpression.NodeType == ExpressionType.NewArrayInit)
766 {
767 stack = Stack.NonEmpty;
768 }
769 ChildRewriter childRewriter = new ChildRewriter(this, stack, newArrayExpression.Expressions.Count);
771 if (childRewriter.Rewrite)
772 {
774 }
775 return childRewriter.Finish(expr);
776 }
777
779 {
783 if (lambdaOperand != null)
784 {
785 childRewriter = new ChildRewriter(this, stack, invocationExpression.ArgumentCount);
787 if (childRewriter.Action == RewriteAction.SpillStack)
788 {
790 }
793 if (childRewriter.Rewrite || stackSpiller._lambdaRewrite != 0)
794 {
796 }
798 return new Result(result.Action | stackSpiller._lambdaRewrite, result.Node);
799 }
800 childRewriter = new ChildRewriter(this, stack, invocationExpression.ArgumentCount + 1);
803 if (childRewriter.Action == RewriteAction.SpillStack)
804 {
806 }
807 return childRewriter.Finish(childRewriter.Rewrite ? new InvocationExpressionN(childRewriter[0], childRewriter[1, -1], invocationExpression.Type) : expr);
808 }
809
811 {
813 ChildRewriter childRewriter = new ChildRewriter(this, stack, newExpression.ArgumentCount);
814 childRewriter.AddArguments(newExpression);
815 if (childRewriter.Action == RewriteAction.SpillStack)
816 {
817 childRewriter.MarkRefArgs(newExpression.Constructor, 0);
818 }
819 return childRewriter.Finish(childRewriter.Rewrite ? new NewExpression(newExpression.Constructor, childRewriter[0, -1], newExpression.Members) : expr);
820 }
821
823 {
825 Result result = RewriteExpression(typeBinaryExpression.Expression, stack);
826 if (result.Action != 0)
827 {
828 expr = new TypeBinaryExpression(result.Node, typeBinaryExpression.TypeOperand, typeBinaryExpression.NodeType);
829 }
830 return new Result(result.Action, expr);
831 }
832
834 {
838 if (stack != 0)
839 {
840 rewriteAction = RewriteAction.SpillStack;
841 }
842 if (rewriteAction != 0)
843 {
844 expr = new UnaryExpression(ExpressionType.Throw, result.Node, unaryExpression.Type, null);
845 }
846 return new Result(rewriteAction, expr);
847 }
848
850 {
852 Result result = RewriteExpression(unaryExpression.Operand, stack);
853 if (result.Action == RewriteAction.SpillStack)
854 {
856 }
857 if (result.Action != 0)
858 {
859 expr = new UnaryExpression(unaryExpression.NodeType, result.Node, unaryExpression.Type, unaryExpression.Method);
860 }
861 return new Result(result.Action, expr);
862 }
863
865 {
867 Result result = RewriteExpression(listInitExpression.NewExpression, stack);
868 Expression node = result.Node;
873 for (int i = 0; i < count; i++)
874 {
876 ChildRewriter childRewriter = new ChildRewriter(this, Stack.NonEmpty, elementInit.Arguments.Count);
877 childRewriter.Add(elementInit.Arguments);
879 array[i] = childRewriter;
880 }
881 switch (rewriteAction)
882 {
883 case RewriteAction.Copy:
884 {
886 for (int k = 0; k < count; k++)
887 {
889 if (childRewriter3.Action == RewriteAction.None)
890 {
892 }
893 else
894 {
896 }
897 }
899 break;
900 }
901 case RewriteAction.SpillStack:
902 {
903 bool flag = IsRefInstance(listInitExpression.NewExpression);
908 if (flag)
909 {
910 parameterExpression2 = MakeTemp(parameterExpression.Type.MakeByRefType());
912 }
913 for (int j = 0; j < count; j++)
914 {
917 }
918 expressions.UncheckedAdd(parameterExpression);
919 expr = MakeBlock(expressions);
920 break;
921 }
922 default:
924 case RewriteAction.None:
925 break;
926 }
927 return new Result(rewriteAction, expr);
928 }
929
931 {
933 Result result = RewriteExpression(memberInitExpression.NewExpression, stack);
934 Expression node = result.Node;
937 int count = bindings.Count;
939 for (int i = 0; i < count; i++)
940 {
941 MemberBinding binding = bindings[i];
942 rewriteAction |= (array[i] = BindingRewriter.Create(binding, this, Stack.NonEmpty)).Action;
943 }
944 switch (rewriteAction)
945 {
946 case RewriteAction.Copy:
947 {
949 for (int k = 0; k < count; k++)
950 {
951 array2[k] = array[k].AsBinding();
952 }
954 break;
955 }
956 case RewriteAction.SpillStack:
957 {
958 bool flag = IsRefInstance(memberInitExpression.NewExpression);
963 if (flag)
964 {
965 parameterExpression2 = MakeTemp(parameterExpression.Type.MakeByRefType());
967 }
968 for (int j = 0; j < count; j++)
969 {
972 expressions.UncheckedAdd(item);
973 }
974 expressions.UncheckedAdd(parameterExpression);
975 expr = MakeBlock(expressions);
976 break;
977 }
978 default:
980 case RewriteAction.None:
981 break;
982 }
983 return new Result(rewriteAction, expr);
984 }
985
987 {
989 int expressionCount = blockExpression.ExpressionCount;
991 Expression[] array = null;
992 for (int i = 0; i < expressionCount; i++)
993 {
994 Expression expression = blockExpression.GetExpression(i);
995 Result result = RewriteExpression(expression, stack);
996 rewriteAction |= result.Action;
997 if (array == null && result.Action != 0)
998 {
999 array = Clone(blockExpression.Expressions, i);
1000 }
1001 if (array != null)
1002 {
1003 array[i] = result.Node;
1004 }
1005 }
1006 if (rewriteAction != 0)
1007 {
1008 expr = blockExpression.Rewrite(null, array);
1009 }
1010 return new Result(rewriteAction, expr);
1011 }
1012
1014 {
1016 Result result = RewriteExpression(labelExpression.DefaultValue, stack);
1017 if (result.Action != 0)
1018 {
1019 expr = new LabelExpression(labelExpression.Target, result.Node);
1020 }
1021 return new Result(result.Action, expr);
1022 }
1023
1025 {
1027 Result result = RewriteExpression(loopExpression.Body, Stack.Empty);
1029 if (stack != 0)
1030 {
1031 rewriteAction = RewriteAction.SpillStack;
1032 }
1033 if (rewriteAction != 0)
1034 {
1035 expr = new LoopExpression(result.Node, loopExpression.BreakLabel, loopExpression.ContinueLabel);
1036 }
1037 return new Result(rewriteAction, expr);
1038 }
1039
1041 {
1045 if (stack != 0)
1046 {
1047 rewriteAction = RewriteAction.SpillStack;
1048 }
1049 if (rewriteAction != 0)
1050 {
1051 expr = Expression.MakeGoto(gotoExpression.Kind, gotoExpression.Target, result.Node, gotoExpression.Type);
1052 }
1053 return new Result(rewriteAction, expr);
1054 }
1055
1057 {
1059 Result result = RewriteExpressionFreeTemps(switchExpression.SwitchValue, stack);
1062 SwitchCase[] array = null;
1063 for (int i = 0; i < readOnlyCollection.Count; i++)
1064 {
1066 Expression[] array2 = null;
1068 for (int j = 0; j < readOnlyCollection2.Count; j++)
1069 {
1071 rewriteAction |= result2.Action;
1072 if (array2 == null && result2.Action != 0)
1073 {
1074 array2 = Clone(readOnlyCollection2, j);
1075 }
1076 if (array2 != null)
1077 {
1078 array2[j] = result2.Node;
1079 }
1080 }
1082 rewriteAction |= result3.Action;
1083 if (result3.Action != 0 || array2 != null)
1084 {
1085 if (array2 != null)
1086 {
1088 }
1090 if (array == null)
1091 {
1092 array = Clone(readOnlyCollection, i);
1093 }
1094 }
1095 if (array != null)
1096 {
1097 array[i] = switchCase;
1098 }
1099 }
1100 Result result4 = RewriteExpression(switchExpression.DefaultBody, stack);
1101 rewriteAction |= result4.Action;
1102 if (rewriteAction != 0)
1103 {
1104 if (array != null)
1105 {
1107 }
1108 expr = new SwitchExpression(switchExpression.Type, result.Node, result4.Node, switchExpression.Comparison, readOnlyCollection);
1109 }
1110 return new Result(rewriteAction, expr);
1111 }
1112
1114 {
1116 Result result = RewriteExpression(tryExpression.Body, Stack.Empty);
1118 CatchBlock[] array = null;
1120 if (readOnlyCollection != null)
1121 {
1122 for (int i = 0; i < readOnlyCollection.Count; i++)
1123 {
1126 Expression filter = catchBlock.Filter;
1127 if (catchBlock.Filter != null)
1128 {
1130 rewriteAction |= result2.Action;
1131 rewriteAction2 |= result2.Action;
1132 filter = result2.Node;
1133 }
1135 rewriteAction |= result3.Action;
1136 if ((rewriteAction2 | result3.Action) != 0)
1137 {
1139 if (array == null)
1140 {
1141 array = Clone(readOnlyCollection, i);
1142 }
1143 }
1144 if (array != null)
1145 {
1146 array[i] = catchBlock;
1147 }
1148 }
1149 }
1151 rewriteAction |= result4.Action;
1153 rewriteAction |= result5.Action;
1154 if (stack != 0)
1155 {
1156 rewriteAction = RewriteAction.SpillStack;
1157 }
1158 if (rewriteAction != 0)
1159 {
1160 if (array != null)
1161 {
1163 }
1164 expr = new TryExpression(tryExpression.Type, result.Node, result5.Node, result4.Node, readOnlyCollection);
1165 }
1166 return new Result(rewriteAction, expr);
1167 }
1168
1170 {
1171 Result result = RewriteExpression(expr.ReduceExtensions(), stack);
1172 return new Result(result.Action | RewriteAction.Copy, result.Node);
1173 }
1174
1176 {
1177 T[] array = new T[original.Count];
1178 for (int i = 0; i < max; i++)
1179 {
1180 array[i] = original[i];
1181 }
1182 return array;
1183 }
1184
1186 {
1187 if (method != null && method.GetParametersCached().Any((ParameterInfo p) => p.ParameterType.IsByRef))
1188 {
1190 }
1191 }
1192
1193 private static void RequireNotRefInstance(Expression instance)
1194 {
1195 if (IsRefInstance(instance))
1196 {
1198 }
1199 }
1200
1201 private static bool IsRefInstance([NotNullWhen(true)] Expression instance)
1202 {
1203 if (instance != null && instance.Type.IsValueType)
1204 {
1205 return instance.Type.GetTypeCode() == TypeCode.Object;
1206 }
1207 return false;
1208 }
1209
1211 {
1212 if (node == null)
1213 {
1214 return new Result(RewriteAction.None, null);
1215 }
1217 {
1218 return _guard.RunOnEmptyStack((StackSpiller @this, Expression n, Stack s) => @this.RewriteExpression(n, s), this, node, stack);
1219 }
1220 Result result;
1221 switch (node.NodeType)
1222 {
1223 case ExpressionType.Add:
1224 case ExpressionType.AddChecked:
1225 case ExpressionType.And:
1226 case ExpressionType.ArrayIndex:
1227 case ExpressionType.Divide:
1228 case ExpressionType.Equal:
1229 case ExpressionType.ExclusiveOr:
1230 case ExpressionType.GreaterThan:
1231 case ExpressionType.GreaterThanOrEqual:
1232 case ExpressionType.LeftShift:
1233 case ExpressionType.LessThan:
1234 case ExpressionType.LessThanOrEqual:
1235 case ExpressionType.Modulo:
1236 case ExpressionType.Multiply:
1237 case ExpressionType.MultiplyChecked:
1238 case ExpressionType.NotEqual:
1239 case ExpressionType.Or:
1240 case ExpressionType.Power:
1241 case ExpressionType.RightShift:
1242 case ExpressionType.Subtract:
1243 case ExpressionType.SubtractChecked:
1244 result = RewriteBinaryExpression(node, stack);
1245 break;
1246 case ExpressionType.AndAlso:
1247 case ExpressionType.Coalesce:
1248 case ExpressionType.OrElse:
1249 result = RewriteLogicalBinaryExpression(node, stack);
1250 break;
1251 case ExpressionType.Assign:
1252 result = RewriteAssignBinaryExpression(node, stack);
1253 break;
1254 case ExpressionType.ArrayLength:
1255 case ExpressionType.Convert:
1256 case ExpressionType.ConvertChecked:
1257 case ExpressionType.Negate:
1258 case ExpressionType.UnaryPlus:
1259 case ExpressionType.NegateChecked:
1260 case ExpressionType.Not:
1261 case ExpressionType.TypeAs:
1262 case ExpressionType.Decrement:
1263 case ExpressionType.Increment:
1264 case ExpressionType.Unbox:
1265 case ExpressionType.OnesComplement:
1266 case ExpressionType.IsTrue:
1267 case ExpressionType.IsFalse:
1268 result = RewriteUnaryExpression(node, stack);
1269 break;
1270 case ExpressionType.Throw:
1271 result = RewriteThrowUnaryExpression(node, stack);
1272 break;
1273 case ExpressionType.Call:
1274 result = RewriteMethodCallExpression(node, stack);
1275 break;
1276 case ExpressionType.Conditional:
1277 result = RewriteConditionalExpression(node, stack);
1278 break;
1279 case ExpressionType.Invoke:
1280 result = RewriteInvocationExpression(node, stack);
1281 break;
1282 case ExpressionType.Lambda:
1283 result = RewriteLambdaExpression(node);
1284 break;
1285 case ExpressionType.ListInit:
1286 result = RewriteListInitExpression(node, stack);
1287 break;
1288 case ExpressionType.MemberAccess:
1289 result = RewriteMemberExpression(node, stack);
1290 break;
1291 case ExpressionType.MemberInit:
1292 result = RewriteMemberInitExpression(node, stack);
1293 break;
1294 case ExpressionType.New:
1295 result = RewriteNewExpression(node, stack);
1296 break;
1297 case ExpressionType.NewArrayInit:
1298 case ExpressionType.NewArrayBounds:
1299 result = RewriteNewArrayExpression(node, stack);
1300 break;
1301 case ExpressionType.TypeIs:
1302 case ExpressionType.TypeEqual:
1303 result = RewriteTypeBinaryExpression(node, stack);
1304 break;
1305 case ExpressionType.Block:
1306 result = RewriteBlockExpression(node, stack);
1307 break;
1308 case ExpressionType.Dynamic:
1310 break;
1311 case ExpressionType.Extension:
1312 result = RewriteExtensionExpression(node, stack);
1313 break;
1314 case ExpressionType.Goto:
1315 result = RewriteGotoExpression(node, stack);
1316 break;
1317 case ExpressionType.Index:
1318 result = RewriteIndexExpression(node, stack);
1319 break;
1320 case ExpressionType.Label:
1321 result = RewriteLabelExpression(node, stack);
1322 break;
1323 case ExpressionType.Loop:
1324 result = RewriteLoopExpression(node, stack);
1325 break;
1326 case ExpressionType.Switch:
1327 result = RewriteSwitchExpression(node, stack);
1328 break;
1329 case ExpressionType.Try:
1330 result = RewriteTryExpression(node, stack);
1331 break;
1332 case ExpressionType.AddAssign:
1333 case ExpressionType.AndAssign:
1334 case ExpressionType.DivideAssign:
1335 case ExpressionType.ExclusiveOrAssign:
1336 case ExpressionType.LeftShiftAssign:
1337 case ExpressionType.ModuloAssign:
1338 case ExpressionType.MultiplyAssign:
1339 case ExpressionType.OrAssign:
1340 case ExpressionType.PowerAssign:
1341 case ExpressionType.RightShiftAssign:
1342 case ExpressionType.SubtractAssign:
1343 case ExpressionType.AddAssignChecked:
1344 case ExpressionType.MultiplyAssignChecked:
1345 case ExpressionType.SubtractAssignChecked:
1346 case ExpressionType.PreIncrementAssign:
1347 case ExpressionType.PreDecrementAssign:
1348 case ExpressionType.PostIncrementAssign:
1349 case ExpressionType.PostDecrementAssign:
1350 result = RewriteReducibleExpression(node, stack);
1351 break;
1352 case ExpressionType.Constant:
1353 case ExpressionType.Parameter:
1354 case ExpressionType.Quote:
1355 case ExpressionType.DebugInfo:
1356 case ExpressionType.Default:
1357 case ExpressionType.RuntimeVariables:
1358 result = new Result(RewriteAction.None, node);
1359 break;
1360 default:
1361 result = RewriteExpression(node.ReduceAndCheck(), stack);
1362 if (result.Action == RewriteAction.None)
1363 {
1364 result = new Result(result.Action | RewriteAction.Copy, result.Node);
1365 }
1366 break;
1367 }
1368 return result;
1369 }
1370
1375
1377 {
1379 }
1380
1385
1387 {
1388 return _tm.Temp(type);
1389 }
1390
1391 private int Mark()
1392 {
1393 return _tm.Mark();
1394 }
1395
1396 private void Free(int mark)
1397 {
1398 _tm.Free(mark);
1399 }
1400
1408}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
void Add(TKey key, TValue value)
static AssignBinaryExpression Make(Expression left, Expression right, bool byRef)
static BinaryExpression Create(ExpressionType nodeType, Expression left, Expression right, Type type, MethodInfo method, LambdaExpression conversion)
static BindingRewriter Create(MemberBinding binding, StackSpiller spiller, Stack stack)
BindingRewriter(MemberBinding binding, StackSpiller spiller)
ChildRewriter(StackSpiller self, Stack stack, int count)
void Add(ReadOnlyCollection< Expression > expressions)
void MarkRefArgs(MethodBase method, int startIndex)
ListBindingRewriter(MemberListBinding binding, StackSpiller spiller, Stack stack)
MemberAssignmentRewriter(MemberAssignment binding, StackSpiller spiller, Stack stack)
MemberMemberBindingRewriter(MemberMemberBinding binding, StackSpiller spiller, Stack stack)
ParameterExpression UseTemp(ParameterExpression temp)
Result RewriteInvocationExpression(Expression expr, Stack stack)
Expression< T > Rewrite< T >(Expression< T > lambda)
Result RewriteConditionalExpression(Expression expr, Stack stack)
Result RewriteSwitchExpression(Expression expr, Stack stack)
Result RewriteMemberInitExpression(Expression expr, Stack stack)
Result RewriteTryExpression(Expression expr, Stack stack)
Result RewriteUnaryExpression(Expression expr, Stack stack)
Result RewriteLogicalBinaryExpression(Expression expr, Stack stack)
Result RewriteExpressionFreeTemps(Expression expression, Stack stack)
ParameterExpression MakeTemp(Type type)
Result RewriteMemberAssignment(BinaryExpression node, Stack stack)
Result RewriteMemberExpression(Expression expr, Stack stack)
static Expression MakeBlock(System.Collections.Generic.ArrayBuilder< Expression > expressions)
Result RewriteNewExpression(Expression expr, Stack stack)
Result RewriteTypeBinaryExpression(Expression expr, Stack stack)
static LambdaExpression AnalyzeLambda(LambdaExpression lambda)
Result RewriteBlockExpression(Expression expr, Stack stack)
static Expression MakeBlock(IReadOnlyList< Expression > expressions)
static void RequireNoRefArgs(MethodBase method)
ParameterExpression ToTemp(Expression expression, out Expression save, bool byRef)
Result RewriteExtensionExpression(Expression expr, Stack stack)
Result RewriteVariableAssignment(BinaryExpression node, Stack stack)
Result RewriteAssignBinaryExpression(Expression expr, Stack stack)
Result RewriteLoopExpression(Expression expr, Stack stack)
Result RewriteMethodCallExpression(Expression expr, Stack stack)
static void RequireNotRefInstance(Expression instance)
Result RewriteIndexExpression(Expression expr, Stack stack)
Result RewriteThrowUnaryExpression(Expression expr, Stack stack)
Result RewriteExpression(Expression node, Stack stack)
static Result RewriteLambdaExpression(Expression expr)
Result RewriteIndexAssignment(BinaryExpression node, Stack stack)
Result RewriteLabelExpression(Expression expr, Stack stack)
Result RewriteNewArrayExpression(Expression expr, Stack stack)
static bool IsRefInstance([NotNullWhen(true)] Expression instance)
static T[] Clone< T >(ReadOnlyCollection< T > original, int max)
Result RewriteListInitExpression(Expression expr, Stack stack)
Result RewriteExtensionAssignment(BinaryExpression node, Stack stack)
Result RewriteReducibleExpression(Expression expr, Stack stack)
Result RewriteBinaryExpression(Expression expr, Stack stack)
Result RewriteGotoExpression(Expression expr, Stack stack)
static Expression MakeBlock(params Expression[] expressions)
static ConditionalExpression Make(Expression test, Expression ifTrue, Expression ifFalse, Type type)
static Exception UnhandledBinding()
Definition Error.cs:638
static Exception TryNotSupportedForValueTypeInstances(object p0)
Definition Error.cs:803
static Exception TryNotSupportedForMethodsWithRefArgs(object p0)
Definition Error.cs:798
static Exception InvalidLvalue(ExpressionType p0)
Definition Error.cs:753
static Exception CannotAutoInitializeValueTypeMemberThroughProperty(object p0)
Definition Error.cs:413
static BlockExpression Block(Expression arg0, Expression arg1)
static MethodInfo GetInvokeMethod(Expression expression)
static CatchBlock MakeCatchBlock(Type type, ParameterExpression? variable, Expression body, Expression? filter)
static GotoExpression MakeGoto(GotoExpressionKind kind, LabelTarget target, Expression? value, Type type)
static PropertyExpression Make(Expression expression, PropertyInfo property)
static NewArrayExpression Make(ExpressionType nodeType, Type type, ReadOnlyCollection< Expression > expressions)
static ParameterExpression Make(Type type, string name, bool isByRef)
static readonly DefaultExpression Empty
Definition Utils.cs:60
bool IsValueType
Definition Type.cs:234
TypeCode
Definition TypeCode.cs:4
Result(RewriteAction action, Expression node)