Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
LambdaCompiler.cs
Go to the documentation of this file.
10
12
13internal sealed class LambdaCompiler : ILocalCache
14{
16
17 [Flags]
18 internal enum CompilationFlags
19 {
22 EmitAsDefaultType = 0x10,
23 EmitAsVoidType = 0x20,
24 EmitAsTail = 0x100,
25 EmitAsMiddle = 0x200,
26 EmitAsNoTail = 0x400,
28 EmitAsTypeMask = 0xF0,
29 EmitAsTailCallMask = 0xF00
30 }
31
32 private sealed class SwitchLabel
33 {
34 internal readonly decimal Key;
35
36 internal readonly Label Label;
37
38 internal readonly object Constant;
39
40 internal SwitchLabel(decimal key, object constant, Label label)
41 {
42 Key = key;
44 Label = label;
45 }
46 }
47
48 private sealed class SwitchInfo
49 {
50 internal readonly SwitchExpression Node;
51
52 internal readonly LocalBuilder Value;
53
54 internal readonly Label Default;
55
56 internal readonly Type Type;
57
58 internal readonly bool IsUnsigned;
59
60 internal readonly bool Is64BitSwitch;
61
63 {
64 Node = node;
65 Value = value;
66 Default = @default;
68 IsUnsigned = Type.IsUnsigned();
69 TypeCode typeCode = Type.GetTypeCode();
70 Is64BitSwitch = typeCode == TypeCode.UInt64 || typeCode == TypeCode.Int64;
71 }
72 }
73
74 private static int s_lambdaMethodIndex;
75
76 private readonly AnalyzedTree _tree;
77
78 private readonly ILGenerator _ilg;
79
80 private readonly MethodInfo _method;
81
83
85
87
88 private readonly LambdaExpression _lambda;
89
90 private readonly bool _hasClosureArgument;
91
93
95
96 private static readonly FieldInfo s_callSiteTargetField = typeof(CallSite<>).GetField("Target");
97
98 private readonly StackGuard _guard = new StackGuard();
99
100 internal ILGenerator IL => _ilg;
101
103
105 {
106 EmitAddress(node, type, CompilationFlags.EmitExpressionStart);
107 }
108
110 {
111 bool flag = (flags & CompilationFlags.EmitExpressionStartMask) == CompilationFlags.EmitExpressionStart;
112 CompilationFlags flags2 = (flag ? EmitExpressionStart(node) : CompilationFlags.EmitNoExpressionStart);
113 switch (node.NodeType)
114 {
115 default:
117 break;
118 case ExpressionType.ArrayIndex:
120 break;
121 case ExpressionType.Parameter:
123 break;
124 case ExpressionType.MemberAccess:
126 break;
127 case ExpressionType.Unbox:
129 break;
130 case ExpressionType.Call:
132 break;
133 case ExpressionType.Index:
135 break;
136 }
137 if (flag)
138 {
140 }
141 }
142
144 {
145 if (TypeUtils.AreEquivalent(type, node.Type))
146 {
147 EmitExpression(node.Left);
148 EmitExpression(node.Right);
150 }
151 else
152 {
154 }
155 }
156
158 {
159 if (TypeUtils.AreEquivalent(type, node.Type))
160 {
161 if (node.IsByRef)
162 {
164 }
165 else
166 {
168 }
169 }
170 else if (node.Type.IsByRef && node.Type.GetElementType() == type)
171 {
173 }
174 else
175 {
177 }
178 }
179
181 {
182 if (TypeUtils.AreEquivalent(type, node.Type))
183 {
184 Type type2 = null;
185 if (node.Expression != null)
186 {
187 EmitInstance(node.Expression, out type2);
188 }
190 }
191 else
192 {
194 }
195 }
196
198 {
199 if (member is FieldInfo { IsLiteral: false, IsInitOnly: false } fieldInfo)
200 {
201 _ilg.EmitFieldAddress(fieldInfo);
202 return;
203 }
204 EmitMemberGet(member, objectType);
208 }
209
211 {
212 if (!node.Method.IsStatic && node.Object.Type.IsArray && node.Method == TypeUtils.GetArrayGetMethod(node.Object.Type))
213 {
216 }
217 else
218 {
220 }
221 }
222
224 {
225 if (!TypeUtils.AreEquivalent(type, node.Type) || node.Indexer != null)
226 {
228 }
229 else if (node.ArgumentCount == 1)
230 {
231 EmitExpression(node.Object);
232 EmitExpression(node.GetArgument(0));
234 }
235 else
236 {
239 }
240 }
241
243 {
244 EmitExpression(node.Operand);
246 }
247
255
257 {
259 WriteBack writeBack = null;
260 if (TypeUtils.AreEquivalent(type, node.Type))
261 {
262 switch (node.NodeType)
263 {
264 case ExpressionType.MemberAccess:
266 break;
267 case ExpressionType.Index:
269 break;
270 }
271 }
272 if (writeBack == null)
273 {
274 EmitAddress(node, type, CompilationFlags.EmitNoExpressionStart | CompilationFlags.EmitAsNoTail);
275 }
276 EmitExpressionEnd(flags);
277 return writeBack;
278 }
279
281 {
282 if (!(node.Member is PropertyInfo { CanWrite: not false }))
283 {
284 return null;
285 }
287 }
288
290 {
292 Type type = null;
293 if (node.Expression != null)
294 {
295 EmitInstance(node.Expression, out type);
298 }
300 EmitCall(type, pi.GetGetMethod(nonPublic: true));
304 return delegate(LambdaCompiler @this)
305 {
306 if (instanceLocal != null)
307 {
308 @this._ilg.Emit(OpCodes.Ldloc, instanceLocal);
309 @this.FreeLocal(instanceLocal);
310 }
311 @this._ilg.Emit(OpCodes.Ldloc, valueLocal);
312 @this.FreeLocal(valueLocal);
313 @this.EmitCall(instanceLocal?.LocalType, pi.GetSetMethod(nonPublic: true));
314 };
315 }
316
318 {
319 if (node.Indexer == null || !node.Indexer.CanWrite)
320 {
321 return null;
322 }
324 }
325
327 {
329 Type type = null;
330 if (node.Object != null)
331 {
332 EmitInstance(node.Object, out type);
335 }
336 int argumentCount = node.ArgumentCount;
338 for (int i = 0; i < argumentCount; i++)
339 {
340 Expression argument = node.GetArgument(i);
345 args[i] = local;
346 }
351 return delegate(LambdaCompiler @this)
352 {
353 if (instanceLocal != null)
354 {
355 @this._ilg.Emit(OpCodes.Ldloc, instanceLocal);
356 @this.FreeLocal(instanceLocal);
357 }
359 foreach (LocalBuilder local2 in array)
360 {
361 @this._ilg.Emit(OpCodes.Ldloc, local2);
362 @this.FreeLocal(local2);
363 }
364 @this._ilg.Emit(OpCodes.Ldloc, valueLocal);
365 @this.FreeLocal(valueLocal);
366 @this.EmitSetIndexCall(node, instanceLocal?.LocalType);
367 };
368 }
369
371 {
372 Type type2 = (type.IsValueType ? type.MakeByRefType() : type);
373 return GetLocal(type2);
374 }
375
377 {
378 EmitBinaryExpression(expr, CompilationFlags.EmitAsNoTail);
379 }
380
382 {
384 if (binaryExpression.Method != null)
385 {
387 return;
388 }
389 if ((binaryExpression.NodeType == ExpressionType.Equal || binaryExpression.NodeType == ExpressionType.NotEqual) && (binaryExpression.Type == typeof(bool) || binaryExpression.Type == typeof(bool?)))
390 {
391 if (ConstantCheck.IsNull(binaryExpression.Left) && !ConstantCheck.IsNull(binaryExpression.Right) && binaryExpression.Right.Type.IsNullableType())
392 {
394 return;
395 }
396 if (ConstantCheck.IsNull(binaryExpression.Right) && !ConstantCheck.IsNull(binaryExpression.Left) && binaryExpression.Left.Type.IsNullableType())
397 {
399 return;
400 }
403 }
404 else
405 {
408 }
409 EmitBinaryOperator(binaryExpression.NodeType, binaryExpression.Left.Type, binaryExpression.Right.Type, binaryExpression.Type, binaryExpression.IsLiftedToNull);
410 }
411
413 {
414 if (isLiftedToNull)
415 {
417 _ilg.EmitDefault(typeof(bool?), this);
418 return;
419 }
420 EmitAddress(e, e.Type);
421 _ilg.EmitHasValue(e.Type);
422 if (op == ExpressionType.Equal)
423 {
426 }
427 }
428
430 {
431 if (b.IsLifted)
432 {
433 ParameterExpression parameterExpression = Expression.Variable(b.Left.Type.GetNonNullableType(), null);
434 ParameterExpression parameterExpression2 = Expression.Variable(b.Right.Type.GetNonNullableType(), null);
436 EmitLift(resultType: (!b.IsLiftedToNull) ? typeof(bool) : methodCallExpression.Type.GetNullableType(), nodeType: b.NodeType, mc: methodCallExpression, paramList: new ParameterExpression[2] { parameterExpression, parameterExpression2 }, argList: new Expression[2] { b.Left, b.Right });
437 }
438 else
439 {
440 EmitMethodCallExpression(Expression.Call(null, b.Method, b.Left, b.Right), flags);
441 }
442 }
443
445 {
446 if (op == ExpressionType.ArrayIndex)
447 {
449 }
450 else if (leftType.IsNullableType() || rightType.IsNullableType())
451 {
453 }
454 else
455 {
457 }
458 }
459
461 {
462 switch (op)
463 {
464 case ExpressionType.NotEqual:
465 if (leftType.GetTypeCode() != TypeCode.Boolean)
466 {
469 goto case ExpressionType.Equal;
470 }
471 goto case ExpressionType.ExclusiveOr;
472 case ExpressionType.Equal:
474 return;
475 case ExpressionType.Add:
477 break;
478 case ExpressionType.AddChecked:
479 _ilg.Emit(leftType.IsFloatingPoint() ? OpCodes.Add : (leftType.IsUnsigned() ? OpCodes.Add_Ovf_Un : OpCodes.Add_Ovf));
480 break;
481 case ExpressionType.Subtract:
483 break;
484 case ExpressionType.SubtractChecked:
485 if (leftType.IsUnsigned())
486 {
488 return;
489 }
490 _ilg.Emit(leftType.IsFloatingPoint() ? OpCodes.Sub : OpCodes.Sub_Ovf);
491 break;
492 case ExpressionType.Multiply:
494 break;
495 case ExpressionType.MultiplyChecked:
496 _ilg.Emit(leftType.IsFloatingPoint() ? OpCodes.Mul : (leftType.IsUnsigned() ? OpCodes.Mul_Ovf_Un : OpCodes.Mul_Ovf));
497 break;
498 case ExpressionType.Divide:
499 _ilg.Emit(leftType.IsUnsigned() ? OpCodes.Div_Un : OpCodes.Div);
500 break;
501 case ExpressionType.Modulo:
502 _ilg.Emit(leftType.IsUnsigned() ? OpCodes.Rem_Un : OpCodes.Rem);
503 return;
504 case ExpressionType.And:
505 case ExpressionType.AndAlso:
507 return;
508 case ExpressionType.Or:
509 case ExpressionType.OrElse:
511 return;
512 case ExpressionType.LessThan:
513 _ilg.Emit(leftType.IsUnsigned() ? OpCodes.Clt_Un : OpCodes.Clt);
514 return;
515 case ExpressionType.LessThanOrEqual:
516 _ilg.Emit((leftType.IsUnsigned() || leftType.IsFloatingPoint()) ? OpCodes.Cgt_Un : OpCodes.Cgt);
519 return;
520 case ExpressionType.GreaterThan:
521 _ilg.Emit(leftType.IsUnsigned() ? OpCodes.Cgt_Un : OpCodes.Cgt);
522 return;
523 case ExpressionType.GreaterThanOrEqual:
524 _ilg.Emit((leftType.IsUnsigned() || leftType.IsFloatingPoint()) ? OpCodes.Clt_Un : OpCodes.Clt);
527 return;
528 case ExpressionType.ExclusiveOr:
530 return;
531 case ExpressionType.LeftShift:
534 break;
535 case ExpressionType.RightShift:
537 _ilg.Emit(leftType.IsUnsigned() ? OpCodes.Shr_Un : OpCodes.Shr);
538 return;
539 }
541 }
542
544 {
545 int value = (leftType.IsInteger64() ? 63 : 31);
546 _ilg.EmitPrimitive(value);
548 }
549
551 {
552 switch (resultType.GetTypeCode())
553 {
554 case TypeCode.Byte:
556 break;
557 case TypeCode.SByte:
558 _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_I1 : OpCodes.Conv_I1);
559 break;
560 case TypeCode.UInt16:
561 _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_U2 : OpCodes.Conv_U2);
562 break;
563 case TypeCode.Int16:
564 _ilg.Emit(IsChecked(op) ? OpCodes.Conv_Ovf_I2 : OpCodes.Conv_I2);
565 break;
566 }
567 }
568
570 {
571 switch (op)
572 {
573 case ExpressionType.And:
574 if (leftType == typeof(bool?))
575 {
577 }
578 else
579 {
581 }
582 break;
583 case ExpressionType.Or:
584 if (leftType == typeof(bool?))
585 {
587 }
588 else
589 {
591 }
592 break;
593 case ExpressionType.Add:
594 case ExpressionType.AddChecked:
595 case ExpressionType.Divide:
596 case ExpressionType.ExclusiveOr:
597 case ExpressionType.LeftShift:
598 case ExpressionType.Modulo:
599 case ExpressionType.Multiply:
600 case ExpressionType.MultiplyChecked:
601 case ExpressionType.RightShift:
602 case ExpressionType.Subtract:
603 case ExpressionType.SubtractChecked:
605 break;
606 case ExpressionType.Equal:
607 case ExpressionType.GreaterThan:
608 case ExpressionType.GreaterThanOrEqual:
609 case ExpressionType.LessThan:
610 case ExpressionType.LessThanOrEqual:
611 case ExpressionType.NotEqual:
612 if (liftedToNull)
613 {
615 }
616 else
617 {
619 }
620 break;
621 }
622 }
623
625 {
626 bool flag = op == ExpressionType.NotEqual;
627 if (flag)
628 {
629 op = ExpressionType.Equal;
630 }
636 _ilg.EmitGetValueOrDefault(type);
638 _ilg.EmitGetValueOrDefault(type);
639 Type nonNullableType = type.GetNonNullableType();
642 _ilg.EmitHasValue(type);
644 _ilg.EmitHasValue(type);
649 if (flag)
650 {
653 }
654 }
655
684
686 {
687 bool flag = leftType.IsNullableType();
688 bool flag2 = rightType.IsNullableType();
696 if (flag)
697 {
699 _ilg.EmitHasValue(leftType);
700 }
701 if (flag2)
702 {
704 _ilg.EmitHasValue(rightType);
705 if (flag)
706 {
708 }
709 }
711 if (flag)
712 {
714 _ilg.EmitGetValueOrDefault(leftType);
715 }
716 else
717 {
719 }
720 if (flag2)
721 {
723 _ilg.EmitGetValueOrDefault(rightType);
724 }
725 else
726 {
728 }
731 Type nonNullableType = resultType.GetNonNullableType();
732 EmitBinaryOperator(op, leftType.GetNonNullableType(), rightType.GetNonNullableType(), nonNullableType, liftedToNull: false);
743 }
744
771
798
800 {
802 {
804 }
805 return value;
806 }
807
814
816 {
817 if (node == null)
818 {
819 return new LabelInfo(_ilg, null, canReturn: false);
820 }
822 labelInfo.Define(_labelBlock);
823 return labelInfo;
824 }
825
830
831 private void PopLabelBlock(LabelScopeKind kind)
832 {
834 }
835
837 {
839 LabelInfo info = null;
840 if (_labelBlock.Kind == LabelScopeKind.Block)
841 {
843 if (info == null && _labelBlock.Parent.Kind == LabelScopeKind.Switch)
844 {
846 }
847 }
848 if (info == null)
849 {
851 }
852 if (labelExpression.DefaultValue != null)
853 {
854 if (labelExpression.Target.Type == typeof(void))
855 {
856 EmitExpressionAsVoid(labelExpression.DefaultValue, flags);
857 }
858 else
859 {
860 flags = UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitExpressionStart);
861 EmitExpression(labelExpression.DefaultValue, flags);
862 }
863 }
864 info.Mark();
865 }
866
868 {
871 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTailCallMask;
872 if (compilationFlags != CompilationFlags.EmitAsNoTail)
873 {
874 compilationFlags = (labelInfo.CanReturn ? CompilationFlags.EmitAsTail : CompilationFlags.EmitAsNoTail);
876 }
877 if (gotoExpression.Value != null)
878 {
879 if (gotoExpression.Target.Type == typeof(void))
880 {
882 }
883 else
884 {
885 flags = UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitExpressionStart);
886 EmitExpression(gotoExpression.Value, flags);
887 }
888 }
889 labelInfo.EmitJump();
891 }
892
894 {
895 if (node.Type != typeof(void) && (flags & CompilationFlags.EmitAsVoidType) == 0)
896 {
897 _ilg.EmitDefault(node.Type, this);
898 }
899 }
900
902 {
903 switch (node.NodeType)
904 {
905 default:
906 if (_labelBlock.Kind != LabelScopeKind.Expression)
907 {
908 PushLabelBlock(LabelScopeKind.Expression);
909 return true;
910 }
911 return false;
912 case ExpressionType.Label:
913 if (_labelBlock.Kind == LabelScopeKind.Block)
914 {
915 LabelTarget target = ((LabelExpression)node).Target;
916 if (_labelBlock.ContainsTarget(target))
917 {
918 return false;
919 }
921 {
922 return false;
923 }
924 }
926 return true;
927 case ExpressionType.Block:
929 {
932 {
934 }
935 return true;
936 }
937 goto default;
938 case ExpressionType.Switch:
939 {
942 foreach (SwitchCase @case in switchExpression.Cases)
943 {
944 DefineBlockLabels(@case.Body);
945 }
947 return true;
948 }
949 case ExpressionType.Convert:
950 if (!(node.Type != typeof(void)))
951 {
953 return true;
954 }
955 goto default;
956 case ExpressionType.Conditional:
957 case ExpressionType.Goto:
958 case ExpressionType.Loop:
960 return true;
961 }
962 }
963
965 {
967 {
968 return;
969 }
970 int i = 0;
971 for (int expressionCount = blockExpression.ExpressionCount; i < expressionCount; i++)
972 {
973 Expression expression = blockExpression.GetExpression(i);
975 {
977 }
978 }
979 }
980
982 {
984 while (true)
985 {
986 switch (expression.NodeType)
987 {
988 default:
989 return;
990 case ExpressionType.Label:
991 {
992 LabelTarget target = ((LabelExpression)expression).Target;
993 _labelInfo.Add(target, new LabelInfo(_ilg, target, TypeUtils.AreReferenceAssignable(lambda.ReturnType, target.Type)));
994 return;
995 }
996 case ExpressionType.Block:
997 {
999 if (blockExpression.ExpressionCount == 0)
1000 {
1001 return;
1002 }
1003 for (int num = blockExpression.ExpressionCount - 1; num >= 0; num--)
1004 {
1005 expression = blockExpression.GetExpression(num);
1007 {
1008 break;
1009 }
1010 }
1011 break;
1012 }
1013 }
1014 }
1015 }
1016
1018 {
1021 DynamicMethod dynamicMethod = new DynamicMethod(lambda.Name ?? ("lambda_method" + num), lambda.ReturnType, parameterTypes, restrictedSkipVisibility: true);
1022 _tree = tree;
1023 _lambda = lambda;
1025 _ilg = dynamicMethod.GetILGenerator();
1026 _hasClosureArgument = true;
1027 _scope = tree.Scopes[lambda];
1028 _boundConstants = tree.Constants[lambda];
1030 }
1031
1042
1043 private void InitializeMethod()
1044 {
1047 }
1048
1050 {
1051 lambda.ValidateArgumentCount();
1054 lambdaCompiler.EmitLambdaBody();
1055 return lambdaCompiler.CreateDelegate();
1056 }
1057
1063
1065 {
1066 return _freeLocals.TryPop(type) ?? _ilg.DeclareLocal(type);
1067 }
1068
1070 {
1071 _freeLocals.Push(local.LocalType, local);
1072 }
1073
1074 internal int GetLambdaArgument(int index)
1075 {
1076 return index + (_hasClosureArgument ? 1 : 0) + ((!_method.IsStatic) ? 1 : 0);
1077 }
1078
1079 internal void EmitLambdaArgument(int index)
1080 {
1081 _ilg.EmitLoadArg(GetLambdaArgument(index));
1082 }
1083
1084 internal void EmitClosureArgument()
1085 {
1086 _ilg.EmitLoadArg(0);
1087 }
1088
1090 {
1092 }
1093
1098
1100 {
1101 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTailCallMask;
1102 return (flags ^ compilationFlags) | newValue;
1103 }
1104
1106 {
1107 CompilationFlags compilationFlags = flags & CompilationFlags.EmitExpressionStartMask;
1108 return (flags ^ compilationFlags) | newValue;
1109 }
1110
1112 {
1113 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTypeMask;
1114 return (flags ^ compilationFlags) | newValue;
1115 }
1116
1118 {
1119 EmitExpression(node, CompilationFlags.EmitExpressionStart | CompilationFlags.EmitAsNoTail);
1120 }
1121
1123 {
1125 }
1126
1128 {
1130 switch (node.NodeType)
1131 {
1132 case ExpressionType.Assign:
1134 break;
1135 case ExpressionType.Block:
1136 Emit((BlockExpression)node, UpdateEmitAsTypeFlag(flags, CompilationFlags.EmitAsVoidType));
1137 break;
1138 case ExpressionType.Throw:
1140 break;
1141 case ExpressionType.Goto:
1143 break;
1144 default:
1145 if (node.Type == typeof(void))
1146 {
1147 EmitExpression(node, UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitNoExpressionStart));
1148 break;
1149 }
1150 EmitExpression(node, CompilationFlags.EmitNoExpressionStart | CompilationFlags.EmitAsNoTail);
1152 break;
1153 case ExpressionType.Constant:
1154 case ExpressionType.Parameter:
1155 case ExpressionType.Default:
1156 break;
1157 }
1159 }
1160
1162 {
1163 if (type == typeof(void))
1164 {
1165 EmitExpressionAsVoid(node, flags);
1166 }
1167 else if (!TypeUtils.AreEquivalent(node.Type, type))
1168 {
1171 }
1172 else
1173 {
1175 }
1176 }
1177
1179 {
1181 {
1182 return CompilationFlags.EmitExpressionStart;
1183 }
1184 return CompilationFlags.EmitNoExpressionStart;
1185 }
1186
1188 {
1189 if ((flags & CompilationFlags.EmitExpressionStartMask) == CompilationFlags.EmitExpressionStart)
1190 {
1192 }
1193 }
1194
1196 {
1198 if (invocationExpression.LambdaOperand != null)
1199 {
1201 return;
1202 }
1203 expr = invocationExpression.Expression;
1204 if (typeof(LambdaExpression).IsAssignableFrom(expr.Type))
1205 {
1207 }
1208 EmitMethodCall(expr, expr.Type.GetInvokeMethod(), invocationExpression, CompilationFlags.EmitExpressionStart | CompilationFlags.EmitAsNoTail);
1209 }
1210
1212 {
1213 LambdaExpression lambdaOperand = invoke.LambdaOperand;
1214 List<WriteBack> list = EmitArguments(lambdaOperand.Type.GetInvokeMethod(), invoke);
1216 if (list != null)
1217 {
1218 flags = UpdateEmitAsTailCallFlag(flags, CompilationFlags.EmitAsNoTail);
1219 }
1220 lambdaCompiler.EmitLambdaBody(_scope, inlined: true, flags);
1222 }
1223
1225 {
1227 Type type = null;
1228 if (indexExpression.Object != null)
1229 {
1231 }
1232 int i = 0;
1233 for (int argumentCount = indexExpression.ArgumentCount; i < argumentCount; i++)
1234 {
1235 Expression argument = indexExpression.GetArgument(i);
1237 }
1239 }
1240
1242 {
1244 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTypeMask;
1245 Type type = null;
1246 if (indexExpression.Object != null)
1247 {
1249 }
1250 int i = 0;
1251 for (int argumentCount = indexExpression.ArgumentCount; i < argumentCount; i++)
1252 {
1253 Expression argument = indexExpression.GetArgument(i);
1255 }
1256 EmitExpression(node.Right);
1257 LocalBuilder local = null;
1258 if (compilationFlags != CompilationFlags.EmitAsVoidType)
1259 {
1262 }
1264 if (compilationFlags != CompilationFlags.EmitAsVoidType)
1265 {
1268 }
1269 }
1270
1272 {
1273 if (node.Indexer != null)
1274 {
1275 MethodInfo getMethod = node.Indexer.GetGetMethod(nonPublic: true);
1277 }
1278 else
1279 {
1281 }
1282 }
1283
1285 {
1286 if (arrayType.IsSZArray)
1287 {
1288 _ilg.EmitLoadElement(arrayType.GetElementType());
1289 }
1290 else
1291 {
1293 }
1294 }
1295
1297 {
1298 if (node.Indexer != null)
1299 {
1300 MethodInfo setMethod = node.Indexer.GetSetMethod(nonPublic: true);
1302 }
1303 else
1304 {
1306 }
1307 }
1308
1310 {
1311 if (arrayType.IsSZArray)
1312 {
1313 _ilg.EmitStoreElement(arrayType.GetElementType());
1314 }
1315 else
1316 {
1318 }
1319 }
1320
1326
1328 {
1329 EmitMethodCallExpression(expr, CompilationFlags.EmitAsNoTail);
1330 }
1331
1336
1338 {
1339 Type type = null;
1340 if (!method.IsStatic)
1341 {
1343 }
1344 if (obj != null && obj.Type.IsValueType)
1345 {
1347 }
1348 else
1349 {
1351 }
1352 }
1353
1358
1360 {
1362 OpCode opCode = (UseVirtual(mi) ? OpCodes.Callvirt : OpCodes.Call);
1363 if (opCode == OpCodes.Callvirt && objectType.IsValueType)
1364 {
1366 }
1367 if ((flags & CompilationFlags.EmitAsTailCallMask) == CompilationFlags.EmitAsTail && !MethodHasByRefParameter(mi))
1368 {
1370 }
1371 if (mi.CallingConvention == CallingConventions.VarArgs)
1372 {
1373 int argumentCount = args.ArgumentCount;
1374 Type[] array = new Type[argumentCount];
1375 for (int i = 0; i < argumentCount; i++)
1376 {
1377 array[i] = args.GetArgument(i).Type;
1378 }
1380 }
1381 else
1382 {
1383 _ilg.Emit(opCode, mi);
1384 }
1386 }
1387
1389 {
1390 ParameterInfo[] parametersCached = mi.GetParametersCached();
1391 foreach (ParameterInfo pi in parametersCached)
1392 {
1393 if (pi.IsByRefParameter())
1394 {
1395 return true;
1396 }
1397 }
1398 return false;
1399 }
1400
1402 {
1403 if (method.CallingConvention == CallingConventions.VarArgs)
1404 {
1406 }
1407 OpCode opCode = (UseVirtual(method) ? OpCodes.Callvirt : OpCodes.Call);
1408 if (opCode == OpCodes.Callvirt && objectType.IsValueType)
1409 {
1411 }
1413 }
1414
1415 private static bool UseVirtual(MethodInfo mi)
1416 {
1417 if (mi.IsStatic)
1418 {
1419 return false;
1420 }
1421 if (mi.DeclaringType.IsValueType)
1422 {
1423 return false;
1424 }
1425 return true;
1426 }
1427
1432
1434 {
1435 ParameterInfo[] parametersCached = method.GetParametersCached();
1436 List<WriteBack> list = null;
1437 int i = skipParameters;
1438 for (int num = parametersCached.Length; i < num; i++)
1439 {
1441 Expression argument = args.GetArgument(i - skipParameters);
1442 Type parameterType = parameterInfo.ParameterType;
1443 if (parameterType.IsByRef)
1444 {
1445 parameterType = parameterType.GetElementType();
1447 if (writeBack != null)
1448 {
1449 if (list == null)
1450 {
1451 list = new List<WriteBack>();
1452 }
1453 list.Add(writeBack);
1454 }
1455 }
1456 else
1457 {
1459 }
1460 }
1461 return list;
1462 }
1463
1465 {
1466 if (writeBacks == null)
1467 {
1468 return;
1469 }
1470 foreach (WriteBack writeBack in writeBacks)
1471 {
1472 writeBack(this);
1473 }
1474 }
1475
1481
1482 private void EmitConstant(object value)
1483 {
1484 EmitConstant(value, value.GetType());
1485 }
1486
1487 private void EmitConstant(object value, Type type)
1488 {
1489 if (!_ilg.TryEmitConstant(value, type, this))
1490 {
1492 }
1493 }
1494
1512
1514 {
1515 return (FieldInfo)siteType.GetMemberWithSameMetadataDefinitionAs(s_callSiteTargetField);
1516 }
1517
1519 {
1521 if (newExpression.Constructor != null)
1522 {
1523 if (newExpression.Constructor.DeclaringType.IsAbstract)
1524 {
1526 }
1528 _ilg.Emit(OpCodes.Newobj, newExpression.Constructor);
1530 }
1531 else
1532 {
1538 }
1539 }
1540
1542 {
1544 if (typeBinaryExpression.NodeType == ExpressionType.TypeEqual)
1545 {
1546 EmitExpression(typeBinaryExpression.ReduceTypeEqual());
1547 return;
1548 }
1549 Type type = typeBinaryExpression.Expression.Type;
1551 switch (analyzeTypeIsResult)
1552 {
1553 case AnalyzeTypeIsResult.KnownFalse:
1554 case AnalyzeTypeIsResult.KnownTrue:
1556 _ilg.EmitPrimitive(analyzeTypeIsResult == AnalyzeTypeIsResult.KnownTrue);
1557 return;
1558 case AnalyzeTypeIsResult.KnownAssignable:
1559 if (type.IsNullableType())
1560 {
1562 _ilg.EmitHasValue(type);
1563 }
1564 else
1565 {
1569 }
1570 return;
1571 }
1573 if (type.IsValueType)
1574 {
1576 }
1580 }
1581
1583 {
1585 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTypeMask;
1586 if (node.IsByRef)
1587 {
1588 EmitAddress(node.Right, node.Right.Type);
1589 }
1590 else
1591 {
1592 EmitExpression(node.Right);
1593 }
1594 if (compilationFlags != CompilationFlags.EmitAsVoidType)
1595 {
1597 }
1598 if (parameterExpression.IsByRef)
1599 {
1605 _ilg.EmitStoreValueIndirect(parameterExpression.Type);
1606 }
1607 else
1608 {
1610 }
1611 }
1612
1614 {
1615 EmitAssign((AssignBinaryExpression)expr, CompilationFlags.EmitAsDefaultType);
1616 }
1617
1619 {
1620 switch (node.Left.NodeType)
1621 {
1622 case ExpressionType.Index:
1624 break;
1625 case ExpressionType.MemberAccess:
1627 break;
1628 case ExpressionType.Parameter:
1630 break;
1631 default:
1633 }
1634 }
1635
1637 {
1640 if (parameterExpression.IsByRef)
1641 {
1642 _ilg.EmitLoadValueIndirect(parameterExpression.Type);
1643 }
1644 }
1645
1651
1657
1659 {
1661 MemberInfo member = memberExpression.Member;
1662 Type type = null;
1663 if (memberExpression.Expression != null)
1664 {
1666 }
1667 EmitExpression(node.Right);
1668 LocalBuilder local = null;
1669 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTypeMask;
1670 if (compilationFlags != CompilationFlags.EmitAsVoidType)
1671 {
1674 }
1675 if (member is FieldInfo)
1676 {
1677 _ilg.EmitFieldSet((FieldInfo)member);
1678 }
1679 else
1680 {
1681 PropertyInfo propertyInfo = (PropertyInfo)member;
1682 EmitCall(type, propertyInfo.GetSetMethod(nonPublic: true));
1683 }
1684 if (compilationFlags != CompilationFlags.EmitAsVoidType)
1685 {
1688 }
1689 }
1690
1692 {
1694 Type type = null;
1695 if (memberExpression.Expression != null)
1696 {
1698 }
1700 }
1701
1703 {
1704 if (member is FieldInfo fieldInfo)
1705 {
1706 if (fieldInfo.IsLiteral)
1707 {
1708 EmitConstant(fieldInfo.GetRawConstantValue(), fieldInfo.FieldType);
1709 }
1710 else
1711 {
1712 _ilg.EmitFieldGet(fieldInfo);
1713 }
1714 }
1715 else
1716 {
1717 PropertyInfo propertyInfo = (PropertyInfo)member;
1718 EmitCall(objectType, propertyInfo.GetGetMethod(nonPublic: true));
1719 }
1720 }
1721
1722 private void EmitInstance(Expression instance, out Type type)
1723 {
1724 type = instance.Type;
1725 if (type.IsByRef)
1726 {
1727 type = type.GetElementType();
1728 EmitExpression(instance);
1729 }
1730 else if (type.IsValueType)
1731 {
1732 EmitAddress(instance, type);
1733 }
1734 else
1735 {
1736 EmitExpression(instance);
1737 }
1738 }
1739
1741 {
1744 int count = expressions.Count;
1745 if (newArrayExpression.NodeType == ExpressionType.NewArrayInit)
1746 {
1747 Type elementType = newArrayExpression.Type.GetElementType();
1748 _ilg.EmitArray(elementType, count);
1749 for (int i = 0; i < count; i++)
1750 {
1752 _ilg.EmitPrimitive(i);
1754 _ilg.EmitStoreElement(elementType);
1755 }
1756 }
1757 else
1758 {
1759 for (int j = 0; j < count; j++)
1760 {
1763 _ilg.EmitConvertToType(expression.Type, typeof(int), isChecked: true, this);
1764 }
1765 _ilg.EmitArray(newArrayExpression.Type);
1766 }
1767 }
1768
1770 {
1771 }
1772
1774 {
1776 }
1777
1779 {
1781 }
1782
1784 {
1785 switch (binding.BindingType)
1786 {
1787 case MemberBindingType.Assignment:
1789 break;
1790 case MemberBindingType.ListBinding:
1792 break;
1793 case MemberBindingType.MemberBinding:
1795 break;
1796 }
1797 }
1798
1800 {
1801 EmitExpression(binding.Expression);
1802 if (binding.Member is FieldInfo field)
1803 {
1805 }
1806 else
1807 {
1808 EmitCall(objectType, (binding.Member as PropertyInfo).GetSetMethod(nonPublic: true));
1809 }
1810 }
1811
1813 {
1815 if (binding.Member is PropertyInfo && memberType.IsValueType)
1816 {
1818 }
1819 if (memberType.IsValueType)
1820 {
1821 EmitMemberAddress(binding.Member, binding.Member.DeclaringType);
1822 }
1823 else
1824 {
1825 EmitMemberGet(binding.Member, binding.Member.DeclaringType);
1826 }
1827 EmitMemberInit(binding.Bindings, keepOnStack: false, memberType);
1828 }
1829
1831 {
1833 if (binding.Member is PropertyInfo && memberType.IsValueType)
1834 {
1836 }
1837 if (memberType.IsValueType)
1838 {
1839 EmitMemberAddress(binding.Member, binding.Member.DeclaringType);
1840 }
1841 else
1842 {
1843 EmitMemberGet(binding.Member, binding.Member.DeclaringType);
1844 }
1845 EmitListInit(binding.Initializers, keepOnStack: false, memberType);
1846 }
1847
1849 {
1850 EmitExpression(init.NewExpression);
1852 if (init.NewExpression.Type.IsValueType && init.Bindings.Count > 0)
1853 {
1854 localBuilder = GetLocal(init.NewExpression.Type);
1857 }
1858 EmitMemberInit(init.Bindings, localBuilder == null, init.NewExpression.Type);
1859 if (localBuilder != null)
1860 {
1863 }
1864 }
1865
1867 {
1868 int count = bindings.Count;
1869 if (count == 0)
1870 {
1871 if (!keepOnStack)
1872 {
1874 }
1875 return;
1876 }
1877 for (int i = 0; i < count; i++)
1878 {
1879 if (keepOnStack || i < count - 1)
1880 {
1882 }
1883 EmitBinding(bindings[i], objectType);
1884 }
1885 }
1886
1888 {
1889 EmitExpression(init.NewExpression);
1891 if (init.NewExpression.Type.IsValueType)
1892 {
1893 localBuilder = GetLocal(init.NewExpression.Type);
1896 }
1897 EmitListInit(init.Initializers, localBuilder == null, init.NewExpression.Type);
1898 if (localBuilder != null)
1899 {
1902 }
1903 }
1904
1906 {
1907 int count = initializers.Count;
1908 if (count == 0)
1909 {
1910 if (!keepOnStack)
1911 {
1913 }
1914 return;
1915 }
1916 for (int i = 0; i < count; i++)
1917 {
1918 if (keepOnStack || i < count - 1)
1919 {
1921 }
1923 if (initializers[i].AddMethod.ReturnType != typeof(void))
1924 {
1926 }
1927 }
1928 }
1929
1930 private static Type GetMemberType(MemberInfo member)
1931 {
1932 if (!(member is FieldInfo fieldInfo))
1933 {
1934 return (member as PropertyInfo).PropertyType;
1935 }
1936 return fieldInfo.FieldType;
1937 }
1938
1940 {
1941 switch (nodeType)
1942 {
1943 default:
1944 {
1950 int j = 0;
1951 for (int num2 = paramList.Length; j < num2; j++)
1952 {
1955 if (expression2.Type.IsNullableType())
1956 {
1957 _scope.AddLocal(this, variable2);
1960 _ilg.EmitHasValue(expression2.Type);
1964 _ilg.EmitGetValueOrDefault(expression2.Type);
1966 }
1967 else
1968 {
1969 _scope.AddLocal(this, variable2);
1971 if (!expression2.Type.IsValueType)
1972 {
1977 }
1979 }
1982 }
1984 if (resultType.IsNullableType() && !TypeUtils.AreEquivalent(resultType, mc.Type))
1985 {
1988 }
1991 if (TypeUtils.AreEquivalent(resultType, mc.Type.GetNullableType()))
1992 {
1993 if (resultType.IsValueType)
1994 {
2000 }
2001 else
2002 {
2004 }
2005 }
2006 else
2007 {
2009 }
2012 break;
2013 }
2014 case ExpressionType.Equal:
2015 case ExpressionType.NotEqual:
2016 if (!TypeUtils.AreEquivalent(resultType, mc.Type.GetNullableType()))
2017 {
2027 int i = 0;
2028 for (int num = paramList.Length; i < num; i++)
2029 {
2032 _scope.AddLocal(this, variable);
2033 if (expression.Type.IsNullableType())
2034 {
2037 _ilg.EmitHasValue(expression.Type);
2047 _ilg.EmitGetValueOrDefault(expression.Type);
2048 }
2049 else
2050 {
2052 if (!expression.Type.IsValueType)
2053 {
2064 }
2065 else
2066 {
2069 }
2070 }
2072 }
2078 if (resultType.IsNullableType() && !TypeUtils.AreEquivalent(resultType, mc.Type))
2079 {
2082 }
2085 _ilg.EmitPrimitive(nodeType == ExpressionType.Equal);
2088 _ilg.EmitPrimitive(nodeType == ExpressionType.NotEqual);
2092 break;
2093 }
2094 goto default;
2095 }
2096 }
2097
2099 {
2101 {
2102 _guard.RunOnEmptyStack(delegate(LambdaCompiler @this, Expression n, CompilationFlags f)
2103 {
2104 @this.EmitExpression(n, f);
2105 }, this, node, flags);
2106 return;
2107 }
2108 bool flag = (flags & CompilationFlags.EmitExpressionStartMask) == CompilationFlags.EmitExpressionStart;
2109 CompilationFlags flags2 = (flag ? EmitExpressionStart(node) : CompilationFlags.EmitNoExpressionStart);
2110 flags &= CompilationFlags.EmitAsTailCallMask;
2111 switch (node.NodeType)
2112 {
2113 case ExpressionType.Add:
2114 case ExpressionType.AddChecked:
2115 case ExpressionType.And:
2116 case ExpressionType.ArrayIndex:
2117 case ExpressionType.Divide:
2118 case ExpressionType.Equal:
2119 case ExpressionType.ExclusiveOr:
2120 case ExpressionType.GreaterThan:
2121 case ExpressionType.GreaterThanOrEqual:
2122 case ExpressionType.LeftShift:
2123 case ExpressionType.LessThan:
2124 case ExpressionType.LessThanOrEqual:
2125 case ExpressionType.Modulo:
2126 case ExpressionType.Multiply:
2127 case ExpressionType.MultiplyChecked:
2128 case ExpressionType.NotEqual:
2129 case ExpressionType.Or:
2130 case ExpressionType.Power:
2131 case ExpressionType.RightShift:
2132 case ExpressionType.Subtract:
2133 case ExpressionType.SubtractChecked:
2134 EmitBinaryExpression(node, flags);
2135 break;
2136 case ExpressionType.AndAlso:
2138 break;
2139 case ExpressionType.OrElse:
2141 break;
2142 case ExpressionType.Coalesce:
2144 break;
2145 case ExpressionType.Assign:
2147 break;
2148 case ExpressionType.ArrayLength:
2149 case ExpressionType.Negate:
2150 case ExpressionType.UnaryPlus:
2151 case ExpressionType.NegateChecked:
2152 case ExpressionType.Not:
2153 case ExpressionType.TypeAs:
2154 case ExpressionType.Decrement:
2155 case ExpressionType.Increment:
2156 case ExpressionType.OnesComplement:
2157 case ExpressionType.IsTrue:
2158 case ExpressionType.IsFalse:
2159 EmitUnaryExpression(node, flags);
2160 break;
2161 case ExpressionType.Convert:
2162 case ExpressionType.ConvertChecked:
2164 break;
2165 case ExpressionType.Quote:
2167 break;
2168 case ExpressionType.Throw:
2170 break;
2171 case ExpressionType.Unbox:
2173 break;
2174 case ExpressionType.Call:
2176 break;
2177 case ExpressionType.Conditional:
2179 break;
2180 case ExpressionType.Constant:
2182 break;
2183 case ExpressionType.Invoke:
2185 break;
2186 case ExpressionType.Lambda:
2188 break;
2189 case ExpressionType.ListInit:
2191 break;
2192 case ExpressionType.MemberAccess:
2194 break;
2195 case ExpressionType.MemberInit:
2197 break;
2198 case ExpressionType.New:
2200 break;
2201 case ExpressionType.NewArrayInit:
2202 case ExpressionType.NewArrayBounds:
2204 break;
2205 case ExpressionType.Parameter:
2207 break;
2208 case ExpressionType.TypeIs:
2209 case ExpressionType.TypeEqual:
2211 break;
2212 case ExpressionType.Block:
2213 EmitBlockExpression(node, flags);
2214 break;
2215 case ExpressionType.DebugInfo:
2217 break;
2218 case ExpressionType.Dynamic:
2220 break;
2221 case ExpressionType.Default:
2223 break;
2224 case ExpressionType.Goto:
2225 EmitGotoExpression(node, flags);
2226 break;
2227 case ExpressionType.Index:
2229 break;
2230 case ExpressionType.Label:
2231 EmitLabelExpression(node, flags);
2232 break;
2233 case ExpressionType.RuntimeVariables:
2235 break;
2236 case ExpressionType.Loop:
2238 break;
2239 case ExpressionType.Switch:
2240 EmitSwitchExpression(node, flags);
2241 break;
2242 case ExpressionType.Try:
2244 break;
2245 }
2246 if (flag)
2247 {
2249 }
2250 }
2251
2252 private static bool IsChecked(ExpressionType op)
2253 {
2254 switch (op)
2255 {
2256 case ExpressionType.AddChecked:
2257 case ExpressionType.ConvertChecked:
2258 case ExpressionType.MultiplyChecked:
2259 case ExpressionType.NegateChecked:
2260 case ExpressionType.SubtractChecked:
2261 case ExpressionType.AddAssignChecked:
2262 case ExpressionType.MultiplyAssignChecked:
2263 case ExpressionType.SubtractAssignChecked:
2264 return true;
2265 default:
2266 return false;
2267 }
2268 }
2269
2270 internal void EmitConstantArray<T>(T[] array)
2271 {
2272 EmitConstant(array, typeof(T[]));
2273 }
2274
2276 {
2277 bool needsClosure = inner._scope.NeedsClosure;
2278 bool flag = inner._boundConstants.Count > 0;
2279 if (!needsClosure && !flag)
2280 {
2281 _ilg.EmitNull();
2282 return;
2283 }
2284 if (flag)
2285 {
2286 _boundConstants.EmitConstant(this, inner._boundConstants.ToArray(), typeof(object[]));
2287 }
2288 else
2289 {
2290 _ilg.EmitNull();
2291 }
2292 if (needsClosure)
2293 {
2295 }
2296 else
2297 {
2298 _ilg.EmitNull();
2299 }
2301 }
2302
2313
2320
2322 {
2323 int parameterCount = lambda.ParameterCount;
2324 Type[] array;
2325 int num;
2326 if (firstType != null)
2327 {
2328 array = new Type[parameterCount + 1];
2329 array[0] = firstType;
2330 num = 1;
2331 }
2332 else
2333 {
2334 array = new Type[parameterCount];
2335 num = 0;
2336 }
2337 int num2 = 0;
2338 while (num2 < parameterCount)
2339 {
2340 ParameterExpression parameter = lambda.GetParameter(num2);
2341 array[num] = (parameter.IsByRef ? parameter.Type.MakeByRefType() : parameter.Type);
2342 num2++;
2343 num++;
2344 }
2345 return array;
2346 }
2347
2348 private void EmitLambdaBody()
2349 {
2350 CompilationFlags flags = (_lambda.TailCall ? CompilationFlags.EmitAsTail : CompilationFlags.EmitAsNoTail);
2351 EmitLambdaBody(null, inlined: false, flags);
2352 }
2353
2354 private void EmitLambdaBody(CompilerScope parent, bool inlined, CompilationFlags flags)
2355 {
2356 _scope.Enter(this, parent);
2357 if (inlined)
2358 {
2359 for (int num = _lambda.ParameterCount - 1; num >= 0; num--)
2360 {
2362 }
2363 }
2364 flags = UpdateEmitExpressionStartFlag(flags, CompilationFlags.EmitExpressionStart);
2365 if (_lambda.ReturnType == typeof(void))
2366 {
2368 }
2369 else
2370 {
2371 EmitExpression(_lambda.Body, flags);
2372 }
2373 if (!inlined)
2374 {
2376 }
2377 _scope.Exit();
2378 foreach (LabelInfo value in _labelInfo.Values)
2379 {
2380 value.ValidateFinish();
2381 }
2382 }
2383
2385 {
2390 if (NotEmpty(conditionalExpression.IfFalse))
2391 {
2393 if ((flags & CompilationFlags.EmitAsTailCallMask) == CompilationFlags.EmitAsTail)
2394 {
2396 }
2397 else
2398 {
2400 }
2404 }
2405 else
2406 {
2408 }
2409 }
2410
2411 private static bool NotEmpty(Expression node)
2412 {
2414 {
2415 return true;
2416 }
2417 return false;
2418 }
2419
2420 private static bool Significant(Expression node)
2421 {
2423 {
2424 for (int i = 0; i < blockExpression.ExpressionCount; i++)
2425 {
2426 if (Significant(blockExpression.GetExpression(i)))
2427 {
2428 return true;
2429 }
2430 }
2431 return false;
2432 }
2433 if (NotEmpty(node))
2434 {
2435 return !(node is DebugInfoExpression);
2436 }
2437 return false;
2438 }
2439
2441 {
2443 if (binaryExpression.Left.Type.IsNullableType())
2444 {
2446 }
2447 else if (binaryExpression.Conversion != null)
2448 {
2450 }
2451 else
2452 {
2454 }
2455 }
2456
2458 {
2459 LocalBuilder local = GetLocal(b.Left.Type);
2462 EmitExpression(b.Left);
2465 _ilg.EmitHasValue(b.Left.Type);
2467 Type nonNullableType = b.Left.Type.GetNonNullableType();
2468 if (b.Conversion != null)
2469 {
2470 ParameterExpression parameter = b.Conversion.GetParameter(0);
2471 EmitLambdaExpression(b.Conversion);
2472 if (!parameter.Type.IsAssignableFrom(b.Left.Type))
2473 {
2475 _ilg.EmitGetValueOrDefault(b.Left.Type);
2476 }
2477 else
2478 {
2480 }
2481 _ilg.Emit(OpCodes.Callvirt, b.Conversion.Type.GetInvokeMethod());
2482 }
2483 else if (TypeUtils.AreEquivalent(b.Type, b.Left.Type))
2484 {
2486 }
2487 else
2488 {
2490 _ilg.EmitGetValueOrDefault(b.Left.Type);
2492 {
2493 _ilg.EmitConvertToType(nonNullableType, b.Type, isChecked: true, this);
2494 }
2495 }
2499 EmitExpression(b.Right);
2500 if (!TypeUtils.AreEquivalent(b.Right.Type, b.Type))
2501 {
2502 _ilg.EmitConvertToType(b.Right.Type, b.Type, isChecked: true, this);
2503 }
2505 }
2506
2508 {
2509 LocalBuilder local = GetLocal(b.Left.Type);
2512 EmitExpression(b.Left);
2516 EmitExpression(b.Right);
2519 EmitLambdaExpression(b.Conversion);
2522 _ilg.Emit(OpCodes.Callvirt, b.Conversion.Type.GetInvokeMethod());
2524 }
2525
2527 {
2530 EmitExpression(b.Left);
2534 EmitExpression(b.Right);
2535 if (!TypeUtils.AreEquivalent(b.Right.Type, b.Type))
2536 {
2537 if (b.Right.Type.IsValueType)
2538 {
2539 _ilg.Emit(OpCodes.Box, b.Right.Type);
2540 }
2541 _ilg.Emit(OpCodes.Castclass, b.Type);
2542 }
2545 if (!TypeUtils.AreEquivalent(b.Left.Type, b.Type))
2546 {
2547 _ilg.Emit(OpCodes.Castclass, b.Type);
2548 }
2550 }
2551
2586
2588 {
2590 EmitExpression(b.Left);
2592 MethodInfo booleanOperator = TypeUtils.GetBooleanOperator(b.Method.DeclaringType, "op_False");
2595 EmitExpression(b.Right);
2596 if ((flags & CompilationFlags.EmitAsTailCallMask) == CompilationFlags.EmitAsTail)
2597 {
2599 }
2600 _ilg.Emit(OpCodes.Call, b.Method);
2602 }
2603
2615
2617 {
2619 if (binaryExpression.Method != null)
2620 {
2621 if (binaryExpression.IsLiftedLogical)
2622 {
2623 EmitExpression(binaryExpression.ReduceUserdefinedLifted());
2624 }
2625 else
2626 {
2628 }
2629 }
2630 else if (binaryExpression.Left.Type == typeof(bool?))
2631 {
2633 }
2634 else
2635 {
2637 }
2638 }
2639
2668
2680
2682 {
2684 EmitExpression(b.Left);
2686 MethodInfo booleanOperator = TypeUtils.GetBooleanOperator(b.Method.DeclaringType, "op_True");
2689 EmitExpression(b.Right);
2690 if ((flags & CompilationFlags.EmitAsTailCallMask) == CompilationFlags.EmitAsTail)
2691 {
2693 }
2694 _ilg.Emit(OpCodes.Call, b.Method);
2696 }
2697
2699 {
2701 if (binaryExpression.Method != null)
2702 {
2703 if (binaryExpression.IsLiftedLogical)
2704 {
2705 EmitExpression(binaryExpression.ReduceUserdefinedLifted());
2706 }
2707 else
2708 {
2710 }
2711 }
2712 else if (binaryExpression.Left.Type == typeof(bool?))
2713 {
2715 }
2716 else
2717 {
2719 }
2720 }
2721
2723 {
2725 switch (node.NodeType)
2726 {
2727 case ExpressionType.Not:
2729 break;
2730 case ExpressionType.AndAlso:
2731 case ExpressionType.OrElse:
2733 break;
2734 case ExpressionType.Block:
2736 break;
2737 case ExpressionType.Equal:
2738 case ExpressionType.NotEqual:
2740 break;
2741 default:
2742 EmitExpression(node, CompilationFlags.EmitNoExpressionStart | CompilationFlags.EmitAsNoTail);
2744 break;
2745 }
2746 EmitExpressionEnd(flags);
2747 }
2748
2749 private void EmitBranchOp(bool branch, Label label)
2750 {
2752 }
2753
2755 {
2756 if (node.Method != null)
2757 {
2758 EmitExpression(node, CompilationFlags.EmitNoExpressionStart | CompilationFlags.EmitAsNoTail);
2760 }
2761 else
2762 {
2764 }
2765 }
2766
2768 {
2769 bool flag = branch == (node.NodeType == ExpressionType.Equal);
2770 if (node.Method != null)
2771 {
2772 EmitBinaryMethod(node, CompilationFlags.EmitAsNoTail);
2774 }
2775 else if (ConstantCheck.IsNull(node.Left))
2776 {
2777 if (node.Right.Type.IsNullableType())
2778 {
2779 EmitAddress(node.Right, node.Right.Type);
2780 _ilg.EmitHasValue(node.Right.Type);
2781 }
2782 else
2783 {
2785 }
2786 EmitBranchOp(!flag, label);
2787 }
2788 else if (ConstantCheck.IsNull(node.Right))
2789 {
2790 if (node.Left.Type.IsNullableType())
2791 {
2792 EmitAddress(node.Left, node.Left.Type);
2793 _ilg.EmitHasValue(node.Left.Type);
2794 }
2795 else
2796 {
2798 }
2799 EmitBranchOp(!flag, label);
2800 }
2801 else if (node.Left.Type.IsNullableType() || node.Right.Type.IsNullableType())
2802 {
2805 }
2806 else
2807 {
2810 _ilg.Emit(flag ? OpCodes.Beq : OpCodes.Bne_Un, label);
2811 }
2812 }
2813
2815 {
2816 if (expression.NodeType == ExpressionType.Convert)
2817 {
2820 {
2821 return unaryExpression.Operand;
2822 }
2823 }
2824 return expression;
2825 }
2826
2828 {
2829 if (node.Method != null || node.IsLifted)
2830 {
2833 return;
2834 }
2835 bool flag = node.NodeType == ExpressionType.AndAlso;
2836 if (branch == flag)
2837 {
2839 }
2840 else
2841 {
2843 }
2844 }
2845
2853
2859
2861 {
2863 int expressionCount = node.ExpressionCount;
2864 for (int i = 0; i < expressionCount - 1; i++)
2865 {
2866 EmitExpressionAsVoid(node.GetExpression(i));
2867 }
2869 ExitScope(node);
2870 }
2871
2873 {
2874 Emit((BlockExpression)expr, UpdateEmitAsTypeFlag(flags, CompilationFlags.EmitAsDefaultType));
2875 }
2876
2878 {
2879 int expressionCount = node.ExpressionCount;
2880 if (expressionCount != 0)
2881 {
2883 CompilationFlags compilationFlags = flags & CompilationFlags.EmitAsTypeMask;
2884 CompilationFlags compilationFlags2 = flags & CompilationFlags.EmitAsTailCallMask;
2885 for (int i = 0; i < expressionCount - 1; i++)
2886 {
2887 Expression expression = node.GetExpression(i);
2888 Expression expression2 = node.GetExpression(i + 1);
2890 flags = UpdateEmitAsTailCallFlag(flags, newValue);
2892 }
2893 if (compilationFlags == CompilationFlags.EmitAsVoidType || node.Type == typeof(void))
2894 {
2896 }
2897 else
2898 {
2900 }
2901 ExitScope(node);
2902 }
2903 }
2904
2905 private void EnterScope(object node)
2906 {
2908 {
2910 {
2911 value = new CompilerScope(node, isMethod: false)
2912 {
2913 NeedsClosure = _scope.NeedsClosure
2914 };
2915 }
2916 _scope = value.Enter(this, _scope);
2917 }
2918 }
2919
2920 private static bool HasVariables(object node)
2921 {
2923 {
2924 return blockExpression.Variables.Count > 0;
2925 }
2926 return ((CatchBlock)node).Variable != null;
2927 }
2928
2929 private void ExitScope(object node)
2930 {
2931 if (_scope.Node == node)
2932 {
2933 _scope = _scope.Exit();
2934 }
2935 }
2936
2938 {
2940 if (defaultExpression.Type != typeof(void))
2941 {
2942 _ilg.EmitDefault(defaultExpression.Type, this);
2943 }
2944 }
2945
2947 {
2949 PushLabelBlock(LabelScopeKind.Statement);
2952 labelInfo2.MarkWithEmptyStack();
2954 _ilg.Emit(OpCodes.Br, labelInfo2.Label);
2955 PopLabelBlock(LabelScopeKind.Statement);
2956 labelInfo.MarkWithEmptyStack();
2957 }
2958
2960 {
2962 if (switchExpression.Cases.Count == 0)
2963 {
2965 if (switchExpression.DefaultBody != null)
2966 {
2967 EmitExpressionAsType(switchExpression.DefaultBody, switchExpression.Type, flags);
2968 }
2969 }
2970 else
2971 {
2973 {
2974 return;
2975 }
2980 EmitExpression(switchExpression.SwitchValue);
2982 Label[] array = new Label[switchExpression.Cases.Count];
2983 bool[] array2 = new bool[switchExpression.Cases.Count];
2984 int i = 0;
2985 for (int count = switchExpression.Cases.Count; i < count; i++)
2986 {
2988 foreach (Expression testValue in switchExpression.Cases[i].TestValues)
2989 {
2993 }
2994 }
2996 Label @default = ((switchExpression.DefaultBody == null) ? label : _ilg.DefineLabel());
2997 EmitSwitchCases(switchExpression, array, array2, @default, label, flags);
2998 }
2999 }
3000
3002 {
3003 if (node.Comparison == null)
3004 {
3005 return node.Cases[0].TestValues[0].Type;
3006 }
3007 Type type = node.Comparison.GetParametersCached()[1].ParameterType.GetNonRefType();
3008 if (node.IsLifted)
3009 {
3010 type = type.GetNullableType();
3011 }
3012 return type;
3013 }
3014
3015 private static bool FitsInBucket(List<SwitchLabel> buckets, decimal key, int count)
3016 {
3017 decimal num = key - buckets[0].Key + 1m;
3018 if (num > 2147483647m)
3019 {
3020 return false;
3021 }
3022 return (decimal)((buckets.Count + count) * 2) > num;
3023 }
3024
3025 private static void MergeBuckets(List<List<SwitchLabel>> buckets)
3026 {
3027 while (buckets.Count > 1)
3028 {
3029 List<SwitchLabel> list = buckets[buckets.Count - 2];
3030 List<SwitchLabel> list2 = buckets[buckets.Count - 1];
3031 if (!FitsInBucket(list, list2[list2.Count - 1].Key, list2.Count))
3032 {
3033 break;
3034 }
3036 buckets.RemoveAt(buckets.Count - 1);
3037 }
3038 }
3039
3040 private static void AddToBuckets(List<List<SwitchLabel>> buckets, SwitchLabel key)
3041 {
3042 if (buckets.Count > 0)
3043 {
3044 List<SwitchLabel> list = buckets[buckets.Count - 1];
3045 if (FitsInBucket(list, key.Key, 1))
3046 {
3047 list.Add(key);
3048 MergeBuckets(buckets);
3049 return;
3050 }
3051 }
3052 buckets.Add(new List<SwitchLabel> { key });
3053 }
3054
3056 {
3057 TypeCode typeCode = valueType.GetTypeCode();
3058 if ((uint)(typeCode - 4) <= 8u)
3059 {
3060 return true;
3061 }
3062 return false;
3063 }
3064
3066 {
3067 if (node.Comparison != null)
3068 {
3069 return false;
3070 }
3071 Type type = node.SwitchValue.Type;
3072 if (!CanOptimizeSwitchType(type) || !TypeUtils.AreEquivalent(type, node.Cases[0].TestValues[0].Type))
3073 {
3074 return false;
3075 }
3076 if (!node.Cases.All((SwitchCase c) => c.TestValues.All((Expression t) => t is ConstantExpression)))
3077 {
3078 return false;
3079 }
3080 Label[] array = new Label[node.Cases.Count];
3081 bool[] array2 = new bool[node.Cases.Count];
3084 for (int i = 0; i < node.Cases.Count; i++)
3085 {
3086 DefineSwitchCaseLabel(node.Cases[i], out array[i], out array2[i]);
3087 foreach (ConstantExpression testValue in node.Cases[i].TestValues)
3088 {
3089 decimal num = ConvertSwitchValue(testValue.Value);
3090 if (hashSet.Add(num))
3091 {
3092 list.Add(new SwitchLabel(num, testValue.Value, array[i]));
3093 }
3094 }
3095 }
3096 list.Sort((SwitchLabel x, SwitchLabel y) => Math.Sign(x.Key - y.Key));
3098 foreach (SwitchLabel item in list)
3099 {
3101 }
3102 LocalBuilder local = GetLocal(node.SwitchValue.Type);
3103 EmitExpression(node.SwitchValue);
3106 Label @default = ((node.DefaultBody == null) ? label : _ilg.DefineLabel());
3107 SwitchInfo info = new SwitchInfo(node, local, @default);
3109 EmitSwitchCases(node, array, array2, @default, label, flags);
3111 return true;
3112 }
3113
3114 private static decimal ConvertSwitchValue(object value)
3115 {
3116 if (value is char)
3117 {
3118 return (int)(char)value;
3119 }
3121 }
3122
3124 {
3125 if (@case.Body is GotoExpression { Value: null } gotoExpression)
3126 {
3128 if (labelInfo.CanBranch)
3129 {
3130 label = labelInfo.Label;
3131 isGoto = true;
3132 return;
3133 }
3134 }
3136 isGoto = false;
3137 }
3138
3139 private void EmitSwitchCases(SwitchExpression node, Label[] labels, bool[] isGoto, Label @default, Label end, CompilationFlags flags)
3140 {
3141 _ilg.Emit(OpCodes.Br, @default);
3142 int i = 0;
3143 for (int count = node.Cases.Count; i < count; i++)
3144 {
3145 if (isGoto[i])
3146 {
3147 continue;
3148 }
3149 _ilg.MarkLabel(labels[i]);
3150 EmitExpressionAsType(node.Cases[i].Body, node.Type, flags);
3151 if (node.DefaultBody != null || i < count - 1)
3152 {
3153 if ((flags & CompilationFlags.EmitAsTailCallMask) == CompilationFlags.EmitAsTail)
3154 {
3156 }
3157 else
3158 {
3159 _ilg.Emit(OpCodes.Br, end);
3160 }
3161 }
3162 }
3163 if (node.DefaultBody != null)
3164 {
3165 _ilg.MarkLabel(@default);
3166 EmitExpressionAsType(node.DefaultBody, node.Type, flags);
3167 }
3168 _ilg.MarkLabel(end);
3169 }
3170
3172 {
3173 while (first != last)
3174 {
3175 int num = (int)(((long)first + (long)last + 1) / 2);
3176 if (first == num - 1)
3177 {
3178 EmitSwitchBucket(info, buckets[first]);
3179 }
3180 else
3181 {
3183 _ilg.Emit(OpCodes.Ldloc, info.Value);
3184 EmitConstant(buckets[num - 1][^1].Constant);
3185 _ilg.Emit(info.IsUnsigned ? OpCodes.Bgt_Un : OpCodes.Bgt, label);
3186 EmitSwitchBuckets(info, buckets, first, num - 1);
3188 }
3189 first = num;
3190 }
3191 EmitSwitchBucket(info, buckets[first]);
3192 }
3193
3195 {
3196 if (bucket.Count == 1)
3197 {
3198 _ilg.Emit(OpCodes.Ldloc, info.Value);
3199 EmitConstant(bucket[0].Constant);
3200 _ilg.Emit(OpCodes.Beq, bucket[0].Label);
3201 return;
3202 }
3203 Label? label = null;
3204 if (info.Is64BitSwitch)
3205 {
3207 _ilg.Emit(OpCodes.Ldloc, info.Value);
3208 EmitConstant(bucket[^1].Constant);
3209 _ilg.Emit(info.IsUnsigned ? OpCodes.Bgt_Un : OpCodes.Bgt, label.Value);
3210 _ilg.Emit(OpCodes.Ldloc, info.Value);
3211 EmitConstant(bucket[0].Constant);
3212 _ilg.Emit(info.IsUnsigned ? OpCodes.Blt_Un : OpCodes.Blt, label.Value);
3213 }
3214 _ilg.Emit(OpCodes.Ldloc, info.Value);
3215 decimal key = bucket[0].Key;
3216 if (key != 0m)
3217 {
3218 EmitConstant(bucket[0].Constant);
3220 }
3221 if (info.Is64BitSwitch)
3222 {
3224 }
3225 int num = (int)(bucket[bucket.Count - 1].Key - bucket[0].Key + 1m);
3226 Label[] array = new Label[num];
3227 int num2 = 0;
3228 foreach (SwitchLabel item in bucket)
3229 {
3230 while (key++ != item.Key)
3231 {
3232 array[num2++] = info.Default;
3233 }
3234 array[num2++] = item.Label;
3235 }
3237 if (info.Is64BitSwitch)
3238 {
3239 _ilg.MarkLabel(label.Value);
3240 }
3241 }
3242
3244 {
3246 {
3247 return false;
3248 }
3249 int num = 0;
3250 foreach (SwitchCase @case in node.Cases)
3251 {
3252 foreach (Expression testValue in @case.TestValues)
3253 {
3255 {
3256 return false;
3257 }
3258 num++;
3259 }
3260 }
3261 if (num < 7)
3262 {
3263 return false;
3264 }
3267 int value = -1;
3269 int i = 0;
3270 for (int count = node.Cases.Count; i < count; i++)
3271 {
3272 foreach (ConstantExpression testValue2 in node.Cases[i].TestValues)
3273 {
3274 if (testValue2.Value != null)
3275 {
3277 }
3278 else
3279 {
3280 value = i;
3281 }
3282 }
3284 }
3290 EmitExpression(node2, flags);
3291 return true;
3292 }
3293
3294 [DynamicDependency("TryGetValue", typeof(Dictionary<, >))]
3295 [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "The method will be preserved by the DynamicDependency.")]
3300
3301 private void CheckRethrow()
3302 {
3304 {
3305 if (labelScopeInfo.Kind == LabelScopeKind.Catch)
3306 {
3307 return;
3308 }
3309 if (labelScopeInfo.Kind == LabelScopeKind.Finally)
3310 {
3311 break;
3312 }
3313 }
3315 }
3316
3317 private void CheckTry()
3318 {
3320 {
3321 if (labelScopeInfo.Kind == LabelScopeKind.Filter)
3322 {
3324 }
3325 }
3326 }
3327
3329 {
3330 if (cb.Variable != null)
3331 {
3333 }
3334 else
3335 {
3337 }
3338 }
3339
3341 {
3343 CheckTry();
3347 Type type = tryExpression.Type;
3348 LocalBuilder local = null;
3349 if (type != typeof(void))
3350 {
3351 local = GetLocal(type);
3353 }
3354 foreach (CatchBlock handler in tryExpression.Handlers)
3355 {
3357 if (handler.Filter == null)
3358 {
3359 _ilg.BeginCatchBlock(handler.Test);
3360 }
3361 else
3362 {
3364 }
3365 EnterScope(handler);
3366 EmitCatchStart(handler);
3367 EmitExpression(handler.Body);
3368 if (type != typeof(void))
3369 {
3371 }
3372 ExitScope(handler);
3374 }
3375 if (tryExpression.Finally != null || tryExpression.Fault != null)
3376 {
3378 if (tryExpression.Finally != null)
3379 {
3381 }
3382 else
3383 {
3385 }
3389 }
3390 else
3391 {
3393 }
3394 if (type != typeof(void))
3395 {
3398 }
3400 }
3401
3403 {
3404 if (cb.Filter == null)
3405 {
3407 return;
3408 }
3423 _ilg.BeginCatchBlock(null);
3425 }
3426
3428 {
3430 }
3431
3443
3445 {
3446 EmitThrow((UnaryExpression)expr, CompilationFlags.EmitAsDefaultType);
3447 }
3448
3450 {
3451 if (expr.Operand == null)
3452 {
3453 CheckRethrow();
3455 }
3456 else
3457 {
3458 EmitExpression(expr.Operand);
3460 }
3461 EmitUnreachable(expr, flags);
3462 }
3463
3465 {
3466 EmitUnary((UnaryExpression)expr, flags);
3467 }
3468
3470 {
3471 if (node.Method != null)
3472 {
3473 EmitUnaryMethod(node, flags);
3474 }
3475 else if (node.NodeType == ExpressionType.NegateChecked && node.Operand.Type.IsInteger())
3476 {
3477 Type type = node.Type;
3478 if (type.IsNullableType())
3479 {
3482 EmitExpression(node.Operand);
3486 _ilg.EmitGetValueOrDefault(type);
3488 Type nonNullableType = type.GetNonNullableType();
3489 _ilg.EmitDefault(nonNullableType, null);
3491 _ilg.EmitGetValueOrDefault(type);
3499 }
3500 else
3501 {
3502 _ilg.EmitDefault(type, null);
3503 EmitExpression(node.Operand);
3504 EmitBinaryOperator(ExpressionType.SubtractChecked, type, type, type, liftedToNull: false);
3505 }
3506 }
3507 else
3508 {
3509 EmitExpression(node.Operand);
3510 EmitUnaryOperator(node.NodeType, node.Operand.Type, node.Type);
3511 }
3512 }
3513
3515 {
3516 bool flag = operandType.IsNullableType();
3517 if (op == ExpressionType.ArrayLength)
3518 {
3520 return;
3521 }
3522 if (flag)
3523 {
3524 switch (op)
3525 {
3526 case ExpressionType.UnaryPlus:
3527 return;
3528 case ExpressionType.TypeAs:
3529 if (operandType != resultType)
3530 {
3533 if (resultType.IsNullableType())
3534 {
3536 }
3537 }
3538 return;
3539 }
3545 _ilg.EmitHasValue(operandType);
3548 _ilg.EmitGetValueOrDefault(operandType);
3549 Type nonNullableType = resultType.GetNonNullableType();
3558 return;
3559 }
3560 switch (op)
3561 {
3562 case ExpressionType.Not:
3563 if (operandType == typeof(bool))
3564 {
3567 return;
3568 }
3569 goto case ExpressionType.OnesComplement;
3570 case ExpressionType.OnesComplement:
3572 if (!operandType.IsUnsigned())
3573 {
3574 return;
3575 }
3576 break;
3577 case ExpressionType.IsFalse:
3580 return;
3581 case ExpressionType.IsTrue:
3584 return;
3585 case ExpressionType.UnaryPlus:
3586 return;
3587 case ExpressionType.Negate:
3588 case ExpressionType.NegateChecked:
3590 return;
3591 case ExpressionType.TypeAs:
3592 if (operandType != resultType)
3593 {
3594 if (operandType.IsValueType)
3595 {
3597 }
3599 if (resultType.IsNullableType())
3600 {
3602 }
3603 }
3604 return;
3605 case ExpressionType.Increment:
3608 break;
3609 case ExpressionType.Decrement:
3612 break;
3613 }
3615 }
3616
3618 {
3619 switch (type.GetTypeCode())
3620 {
3621 case TypeCode.Int64:
3622 case TypeCode.UInt64:
3625 break;
3626 case TypeCode.Single:
3627 _ilg.Emit(OpCodes.Ldc_R4, 1f);
3628 break;
3629 case TypeCode.Double:
3630 _ilg.Emit(OpCodes.Ldc_R8, 1.0);
3631 break;
3632 default:
3634 break;
3635 }
3636 }
3637
3644
3646 {
3647 EmitConvert((UnaryExpression)expr, flags);
3648 }
3649
3651 {
3652 if (node.Method != null)
3653 {
3654 if (!node.IsLifted || (node.Type.IsValueType && node.Operand.Type.IsValueType))
3655 {
3656 EmitUnaryMethod(node, flags);
3657 return;
3658 }
3659 ParameterInfo[] parametersCached = node.Method.GetParametersCached();
3660 Type type = parametersCached[0].ParameterType;
3661 if (type.IsByRef)
3662 {
3663 type = type.GetElementType();
3664 }
3666 node = Expression.Convert(Expression.Call(node.Method, arg), node.Type);
3667 }
3668 if (node.Type == typeof(void))
3669 {
3670 EmitExpressionAsVoid(node.Operand, flags);
3671 return;
3672 }
3673 if (TypeUtils.AreEquivalent(node.Operand.Type, node.Type))
3674 {
3675 EmitExpression(node.Operand, flags);
3676 return;
3677 }
3678 EmitExpression(node.Operand);
3679 _ilg.EmitConvertToType(node.Operand.Type, node.Type, node.NodeType == ExpressionType.ConvertChecked, this);
3680 }
3681
3683 {
3684 if (node.IsLifted)
3685 {
3686 ParameterExpression parameterExpression = Expression.Variable(node.Operand.Type.GetNonNullableType(), null);
3688 Type nullableType = methodCallExpression.Type.GetNullableType();
3689 EmitLift(node.NodeType, nullableType, methodCallExpression, new ParameterExpression[1] { parameterExpression }, new Expression[1] { node.Operand });
3690 _ilg.EmitConvertToType(nullableType, node.Type, isChecked: false, this);
3691 }
3692 else
3693 {
3694 EmitMethodCallExpression(Expression.Call(node.Method, node.Operand), flags);
3695 }
3696 }
3697}
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
bool ICollection< KeyValuePair< TKey, TValue > >. Contains(KeyValuePair< TKey, TValue > keyValuePair)
void AddRange(IEnumerable< KeyValuePair< TKey, TValue > > collection)
void Add(TKey key, TValue value)
static decimal ToDecimal(object? value)
Definition Convert.cs:2101
static ConstructorInfo GetNullableConstructor(Type nullableType)
Definition TypeUtils.cs:34
static MethodInfo GetArrayGetMethod(Type arrayType)
Definition TypeUtils.cs:769
static bool AreEquivalent(Type t1, Type t2)
Definition TypeUtils.cs:664
static MethodInfo GetBooleanOperator(Type type, string name)
Definition TypeUtils.cs:640
static bool AreReferenceAssignable(Type dest, Type src)
Definition TypeUtils.cs:673
static MethodInfo GetArraySetMethod(Type arrayType)
Definition TypeUtils.cs:775
static MethodInfo GetArrayAddressMethod(Type arrayType)
Definition TypeUtils.cs:781
static CultureInfo InvariantCulture
ParameterExpression? Variable
Definition CatchBlock.cs:8
readonly Dictionary< object, CompilerScope > Scopes
void EmitConstant(LambdaCompiler lc, object value, Type type)
void EmitSet(ParameterExpression variable)
void EmitGet(ParameterExpression variable)
CompilerScope Enter(LambdaCompiler lc, CompilerScope parent)
void EmitAddressOf(ParameterExpression variable)
void EmitVariableAccess(LambdaCompiler lc, ReadOnlyCollection< ParameterExpression > vars)
void AddLocal(LambdaCompiler gen, ParameterExpression variable)
readonly ParameterExpression SelfVariable
bool TryGetLabelInfo(LabelTarget target, out LabelInfo info)
SwitchInfo(SwitchExpression node, LocalBuilder value, Label @default)
SwitchLabel(decimal key, object constant, Label label)
static Delegate Compile(LambdaExpression lambda)
void EmitInstance(Expression instance, out Type type)
void EmitSwitchBuckets(SwitchInfo info, List< List< SwitchLabel > > buckets, int first, int last)
void EmitMethodAndAlso(BinaryExpression b, CompilationFlags flags)
MemberExpression CreateLazyInitializedField< T >(string name)
static CompilationFlags UpdateEmitAsTypeFlag(CompilationFlags flags, CompilationFlags newValue)
void EmitCall(Type objectType, MethodInfo method)
void AddressOf(ParameterExpression node, Type type)
void EmitMemberListBinding(MemberListBinding binding)
void EmitMethodCall(MethodInfo mi, IArgumentProvider args, Type objectType, CompilationFlags flags)
void EmitConvertUnaryExpression(Expression expr, CompilationFlags flags)
static Type GetTestValueType(SwitchExpression node)
void EmitReferenceCoalesceWithoutConversion(BinaryExpression b)
void EmitUnaryMethod(UnaryExpression node, CompilationFlags flags)
void EmitLiftedToNullRelational(ExpressionType op, Type type)
void EmitBranchNot(bool branch, UnaryExpression node, Label label)
void EmitBlockExpression(Expression expr, CompilationFlags flags)
void EmitAddress(Expression node, Type type)
LambdaCompiler(LambdaCompiler parent, LambdaExpression lambda, InvocationExpression invocation)
void EmitLift(ExpressionType nodeType, Type resultType, MethodCallExpression mc, ParameterExpression[] paramList, Expression[] argList)
static void MergeBuckets(List< List< SwitchLabel > > buckets)
void EmitLambdaBody(CompilerScope parent, bool inlined, CompilationFlags flags)
void EmitMethodCall(Expression obj, MethodInfo method, IArgumentProvider methodCallExpr)
void EmitSwitchBucket(SwitchInfo info, List< SwitchLabel > bucket)
static Expression GetEqualityOperand(Expression expression)
WriteBack AddressOfWriteBackCore(IndexExpression node)
readonly KeyedStack< Type, LocalBuilder > _freeLocals
void EmitAddress(Expression node, Type type, CompilationFlags flags)
bool TryEmitHashtableSwitch(SwitchExpression node, CompilationFlags flags)
bool TryEmitSwitchInstruction(SwitchExpression node, CompilationFlags flags)
WriteBack AddressOfWriteBack(MemberExpression node)
void EmitAndAlsoBinaryExpression(Expression expr, CompilationFlags flags)
void EmitUnaryExpression(Expression expr, CompilationFlags flags)
void EmitMethodCallExpression(Expression expr, CompilationFlags flags)
void EmitUnary(UnaryExpression node, CompilationFlags flags)
void AddressOf(MethodCallExpression node, Type type)
void EmitSwitchExpression(Expression expr, CompilationFlags flags)
WriteBack EmitAddressWriteBack(Expression node, Type type)
delegate void WriteBack(LambdaCompiler compiler)
void EmitVariableAssignment(AssignBinaryExpression node, CompilationFlags flags)
void EmitLiftedBinaryOp(ExpressionType op, Type leftType, Type rightType, Type resultType, bool liftedToNull)
void EmitExpressionAsVoid(Expression node, CompilationFlags flags)
void EmitMemberInit(ReadOnlyCollection< MemberBinding > bindings, bool keepOnStack, Type objectType)
WriteBack AddressOfWriteBackCore(MemberExpression node)
void EmitExpressionAddress(Expression node, Type type)
static Type[] GetParameterTypes(LambdaExpression lambda, Type firstType)
void EmitGetIndexCall(IndexExpression node, Type objectType)
void EmitExpressionAndBranch(bool branchValue, Expression node, Label label)
void EmitMemberInit(MemberInitExpression init)
void EmitBinding(MemberBinding binding, Type objectType)
void EmitIndexAssignment(AssignBinaryExpression node, CompilationFlags flags)
static FieldInfo GetCallSiteTargetField(Type siteType)
void EmitListInit(ReadOnlyCollection< ElementInit > initializers, bool keepOnStack, Type objectType)
void EmitBranchLogical(bool branch, BinaryExpression node, Label label)
void EmitMemberMemberBinding(MemberMemberBinding binding)
void EmitBinaryOperator(ExpressionType op, Type leftType, Type rightType, Type resultType, bool liftedToNull)
void AddressOf(UnaryExpression node, Type type)
void EmitMethodOrElse(BinaryExpression b, CompilationFlags flags)
void AddressOf(IndexExpression node, Type type)
static void AddToBuckets(List< List< SwitchLabel > > buckets, SwitchLabel key)
void EmitInlinedInvoke(InvocationExpression invoke, CompilationFlags flags)
void EmitLiftedBinaryArithmetic(ExpressionType op, Type leftType, Type rightType, Type resultType)
static bool FitsInBucket(List< SwitchLabel > buckets, decimal key, int count)
void EmitConvertArithmeticResult(ExpressionType op, Type resultType)
void Emit(BlockExpression node, CompilationFlags flags)
void EmitOrElseBinaryExpression(Expression expr, CompilationFlags flags)
void EmitAssign(AssignBinaryExpression node, CompilationFlags emitAs)
void EmitUnliftedBinaryOp(ExpressionType op, Type leftType, Type rightType)
void EmitBranchBlock(bool branch, BlockExpression node, Label label)
void EmitLiftedRelational(ExpressionType op, Type type)
CompilationFlags EmitExpressionStart(Expression node)
void DefineSwitchCaseLabel(SwitchCase @case, out Label label, out bool isGoto)
void EmitBranchAnd(bool branch, BinaryExpression node, Label label)
void EmitConvert(UnaryExpression node, CompilationFlags flags)
void EmitBinaryExpression(Expression expr, CompilationFlags flags)
void EmitMethodCall(MethodInfo mi, IArgumentProvider args, Type objectType)
void EmitBinaryMethod(BinaryExpression b, CompilationFlags flags)
static AnalyzedTree AnalyzeLambda(ref LambdaExpression lambda)
WriteBack AddressOfWriteBack(IndexExpression node)
List< WriteBack > EmitArguments(MethodBase method, IArgumentProvider args, int skipParameters)
static CompilationFlags UpdateEmitAsTailCallFlag(CompilationFlags flags, CompilationFlags newValue)
void EmitMemberAssignment(AssignBinaryExpression node, CompilationFlags flags)
void EmitInvocationExpression(Expression expr, CompilationFlags flags)
static MethodCallExpression CallTryGetValue(Expression dictInit, ParameterExpression switchValue, ParameterExpression switchIndex)
void AddressOf(MemberExpression node, Type type)
void EmitConditionalExpression(Expression expr, CompilationFlags flags)
void EmitDelegateConstruction(LambdaExpression lambda)
void EmitUnaryOperator(ExpressionType op, Type operandType, Type resultType)
void EmitSwitchCases(SwitchExpression node, Label[] labels, bool[] isGoto, Label @default, Label end, CompilationFlags flags)
void EmitMemberAddress(MemberInfo member, Type objectType)
void EmitThrow(UnaryExpression expr, CompilationFlags flags)
void EmitWriteBack(List< WriteBack > writeBacks)
void EmitBranchComparison(bool branch, BinaryExpression node, Label label)
void EmitExpressionAsType(Expression node, Type type, CompilationFlags flags)
void EmitMemberGet(MemberInfo member, Type objectType)
void EmitMemberAssignment(MemberAssignment binding, Type objectType)
List< WriteBack > EmitArguments(MethodBase method, IArgumentProvider args)
void EmitLabelExpression(Expression expr, CompilationFlags flags)
void AddressOf(BinaryExpression node, Type type)
void EmitBranchOr(bool branch, BinaryExpression node, Label label)
void EmitNullEquality(ExpressionType op, Expression e, bool isLiftedToNull)
void EmitGotoExpression(Expression expr, CompilationFlags flags)
readonly Dictionary< LabelTarget, LabelInfo > _labelInfo
void EmitSetIndexCall(IndexExpression node, Type objectType)
LambdaCompiler(AnalyzedTree tree, LambdaExpression lambda)
void EmitUnreachable(Expression node, CompilationFlags flags)
void EmitMethodCall(Expression obj, MethodInfo method, IArgumentProvider methodCallExpr, CompilationFlags flags)
void EmitExpression(Expression node, CompilationFlags flags)
static CompilationFlags UpdateEmitExpressionStartFlag(CompilationFlags flags, CompilationFlags newValue)
static LambdaExpression AnalyzeLambda(LambdaExpression lambda)
static AnalyzedTree Bind(LambdaExpression lambda)
static AnalyzeTypeIsResult AnalyzeTypeIs(TypeBinaryExpression typeIs)
static bool IsNull(Expression e)
static Exception TryNotAllowedInFilter()
Definition Error.cs:778
static Exception NonAbstractConstructorRequired()
Definition Error.cs:833
static Exception CannotAutoInitializeValueTypeElementThroughProperty(object p0)
Definition Error.cs:408
static Exception RethrowRequiresCatch()
Definition Error.cs:773
static Exception UnexpectedVarArgsCall(object p0)
Definition Error.cs:768
static Exception CannotAutoInitializeValueTypeMemberThroughProperty(object p0)
Definition Error.cs:413
static SwitchExpression Switch(Expression switchValue, params SwitchCase[]? cases)
static ConstantExpression Constant(object? value)
static BlockExpression Block(Expression arg0, Expression arg1)
static MethodCallExpression Call(MethodInfo method)
static BinaryExpression Assign(Expression left, Expression right)
static SwitchCase SwitchCase(Expression body, params Expression[] testValues)
static ParameterExpression Parameter(Type type)
static ListInitExpression ListInit(NewExpression newExpression, params Expression[] initializers)
static ConditionalExpression IfThenElse(Expression test, Expression ifTrue, Expression ifFalse)
static ElementInit ElementInit(MethodInfo addMethod, params Expression[] arguments)
static ConditionalExpression Condition(Expression test, Expression ifTrue, Expression ifFalse)
static NewExpression New(ConstructorInfo constructor)
static UnaryExpression Convert(Expression expression, Type type)
static BinaryExpression Equal(Expression left, Expression right)
static ParameterExpression Variable(Type type)
ParameterExpression IParameterProvider. GetParameter(int index)
static MethodInfo GetCompileMethod(Type lambdaExpressionType)
ReadOnlyCollection< Expression > TestValues
Definition SwitchCase.cs:11
static ConstantExpression Constant(bool value)
Definition Utils.cs:64
static readonly DefaultExpression Empty
Definition Utils.cs:60
static MemberExpression GetStrongBoxValueField(Expression strongbox)
Definition Utils.cs:88
static int Sign(decimal value)
Definition Math.cs:1202
virtual LocalBuilder DeclareLocal(Type localType)
virtual void MarkLabel(Label loc)
virtual void Emit(OpCode opcode)
virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
virtual void BeginCatchBlock(Type exceptionType)
static readonly OpCode Castclass
Definition OpCodes.cs:235
static readonly OpCode Ldloca
Definition OpCodes.cs:427
static readonly OpCode Unbox
Definition OpCodes.cs:241
static readonly OpCode Brfalse
Definition OpCodes.cs:117
static readonly OpCode Conv_I4
Definition OpCodes.cs:213
static readonly OpCode Blt_Un
Definition OpCodes.cs:139
static readonly OpCode Rem
Definition OpCodes.cs:189
static readonly OpCode Tailcall
Definition OpCodes.cs:439
static readonly OpCode Unbox_Any
Definition OpCodes.cs:329
static readonly OpCode Blt
Definition OpCodes.cs:129
static readonly OpCode Callvirt
Definition OpCodes.cs:225
static readonly OpCode Mul
Definition OpCodes.cs:183
static readonly OpCode Brtrue
Definition OpCodes.cs:119
static readonly OpCode Clt
Definition OpCodes.cs:411
static readonly OpCode Br_S
Definition OpCodes.cs:89
static readonly OpCode Conv_I2
Definition OpCodes.cs:211
static readonly OpCode Or
Definition OpCodes.cs:195
static readonly OpCode Sub_Ovf
Definition OpCodes.cs:373
static readonly OpCode Stloc
Definition OpCodes.cs:429
static readonly OpCode Bgt_Un
Definition OpCodes.cs:135
static readonly OpCode Conv_Ovf_U1
Definition OpCodes.cs:333
static readonly OpCode Constrained
Definition OpCodes.cs:443
static readonly OpCode Newobj
Definition OpCodes.cs:233
static readonly OpCode Bgt
Definition OpCodes.cs:125
static readonly OpCode Cgt
Definition OpCodes.cs:407
static readonly OpCode Conv_I1
Definition OpCodes.cs:209
static readonly OpCode Add
Definition OpCodes.cs:179
static readonly OpCode Beq
Definition OpCodes.cs:121
static readonly OpCode And
Definition OpCodes.cs:193
static readonly OpCode Br
Definition OpCodes.cs:115
static readonly OpCode Shl
Definition OpCodes.cs:199
static readonly OpCode Initobj
Definition OpCodes.cs:441
static readonly OpCode Conv_U1
Definition OpCodes.cs:357
static readonly OpCode Bne_Un
Definition OpCodes.cs:131
static readonly OpCode Mul_Ovf
Definition OpCodes.cs:369
static readonly OpCode Ceq
Definition OpCodes.cs:405
static readonly OpCode Ldfld
Definition OpCodes.cs:245
static readonly OpCode Shr
Definition OpCodes.cs:201
static readonly OpCode Ldc_I4_1
Definition OpCodes.cs:51
static readonly OpCode Sub
Definition OpCodes.cs:181
static readonly OpCode Ldc_I4_0
Definition OpCodes.cs:49
static readonly OpCode Isinst
Definition OpCodes.cs:237
static readonly OpCode Throw
Definition OpCodes.cs:243
static readonly OpCode Brtrue_S
Definition OpCodes.cs:93
static readonly OpCode Pop
Definition OpCodes.cs:79
static readonly OpCode Conv_U2
Definition OpCodes.cs:355
static readonly OpCode Ldelema
Definition OpCodes.cs:285
static readonly OpCode Switch
Definition OpCodes.cs:141
static readonly OpCode Shr_Un
Definition OpCodes.cs:203
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 Ldnull
Definition OpCodes.cs:45
static readonly OpCode Brfalse_S
Definition OpCodes.cs:91
static readonly OpCode Ldc_R4
Definition OpCodes.cs:73
static readonly OpCode Box
Definition OpCodes.cs:279
static readonly OpCode Neg
Definition OpCodes.cs:205
static readonly OpCode Not
Definition OpCodes.cs:207
static readonly OpCode Div
Definition OpCodes.cs:185
static readonly OpCode Ldc_R8
Definition OpCodes.cs:75
static readonly OpCode Xor
Definition OpCodes.cs:197
static readonly OpCode Add_Ovf
Definition OpCodes.cs:365
static readonly OpCode Dup
Definition OpCodes.cs:77
static readonly OpCode Stfld
Definition OpCodes.cs:249
static readonly OpCode Rethrow
Definition OpCodes.cs:449
static readonly OpCode Conv_I8
Definition OpCodes.cs:215
static readonly OpCode Sub_Ovf_Un
Definition OpCodes.cs:375
static readonly OpCode Ldlen
Definition OpCodes.cs:283
static readonly OpCode Cgt_Un
Definition OpCodes.cs:409
virtual Delegate CreateDelegate(Type delegateType)
Definition MethodInfo.cs:48
static int Increment(ref int location)
static ? Type GetType(string typeName, bool throwOnError, bool ignoreCase)
Definition Type.cs:408
static TypeCode GetTypeCode(Type? type)
Definition Type.cs:919
TypeCode
Definition TypeCode.cs:4