1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Microsoft Public License. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Microsoft Public License, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Microsoft Public License.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
18 using System.Diagnostics;
20 using System.Dynamic.Utils;
22 using Microsoft.Scripting.Utils;
26 namespace System.Linq.Expressions.Compiler {
28 namespace Microsoft.Linq.Expressions.Compiler {
30 partial class LambdaCompiler {
32 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
33 private void EmitExpression(Expression node, CompilationFlags flags) {
34 Debug.Assert(node != null);
36 bool emitStart = (flags & CompilationFlags.EmitExpressionStartMask) == CompilationFlags.EmitExpressionStart;
38 CompilationFlags startEmitted = emitStart ? EmitExpressionStart(node) : CompilationFlags.EmitNoExpressionStart;
39 // only pass tail call flags to emit the expression
40 flags = flags & CompilationFlags.EmitAsTailCallMask;
42 switch (node.NodeType) {
43 #region Generated Expression Compiler
45 // *** BEGIN GENERATED CODE ***
46 // generated by function: gen_compiler from: generate_tree.py
48 case ExpressionType.Add:
49 EmitBinaryExpression(node, flags);
51 case ExpressionType.AddChecked:
52 EmitBinaryExpression(node, flags);
54 case ExpressionType.And:
55 EmitBinaryExpression(node, flags);
57 case ExpressionType.AndAlso:
58 EmitAndAlsoBinaryExpression(node, flags);
60 case ExpressionType.ArrayLength:
61 EmitUnaryExpression(node, flags);
63 case ExpressionType.ArrayIndex:
64 EmitBinaryExpression(node, flags);
66 case ExpressionType.Call:
67 EmitMethodCallExpression(node, flags);
69 case ExpressionType.Coalesce:
70 EmitCoalesceBinaryExpression(node);
72 case ExpressionType.Conditional:
73 EmitConditionalExpression(node, flags);
75 case ExpressionType.Constant:
76 EmitConstantExpression(node);
78 case ExpressionType.Convert:
79 EmitConvertUnaryExpression(node, flags);
81 case ExpressionType.ConvertChecked:
82 EmitConvertUnaryExpression(node, flags);
84 case ExpressionType.Divide:
85 EmitBinaryExpression(node, flags);
87 case ExpressionType.Equal:
88 EmitBinaryExpression(node, flags);
90 case ExpressionType.ExclusiveOr:
91 EmitBinaryExpression(node, flags);
93 case ExpressionType.GreaterThan:
94 EmitBinaryExpression(node, flags);
96 case ExpressionType.GreaterThanOrEqual:
97 EmitBinaryExpression(node, flags);
99 case ExpressionType.Invoke:
100 EmitInvocationExpression(node, flags);
102 case ExpressionType.Lambda:
103 EmitLambdaExpression(node);
105 case ExpressionType.LeftShift:
106 EmitBinaryExpression(node, flags);
108 case ExpressionType.LessThan:
109 EmitBinaryExpression(node, flags);
111 case ExpressionType.LessThanOrEqual:
112 EmitBinaryExpression(node, flags);
114 case ExpressionType.ListInit:
115 EmitListInitExpression(node);
117 case ExpressionType.MemberAccess:
118 EmitMemberExpression(node);
120 case ExpressionType.MemberInit:
121 EmitMemberInitExpression(node);
123 case ExpressionType.Modulo:
124 EmitBinaryExpression(node, flags);
126 case ExpressionType.Multiply:
127 EmitBinaryExpression(node, flags);
129 case ExpressionType.MultiplyChecked:
130 EmitBinaryExpression(node, flags);
132 case ExpressionType.Negate:
133 EmitUnaryExpression(node, flags);
135 case ExpressionType.UnaryPlus:
136 EmitUnaryExpression(node, flags);
138 case ExpressionType.NegateChecked:
139 EmitUnaryExpression(node, flags);
141 case ExpressionType.New:
142 EmitNewExpression(node);
144 case ExpressionType.NewArrayInit:
145 EmitNewArrayExpression(node);
147 case ExpressionType.NewArrayBounds:
148 EmitNewArrayExpression(node);
150 case ExpressionType.Not:
151 EmitUnaryExpression(node, flags);
153 case ExpressionType.NotEqual:
154 EmitBinaryExpression(node, flags);
156 case ExpressionType.Or:
157 EmitBinaryExpression(node, flags);
159 case ExpressionType.OrElse:
160 EmitOrElseBinaryExpression(node, flags);
162 case ExpressionType.Parameter:
163 EmitParameterExpression(node);
165 case ExpressionType.Power:
166 EmitBinaryExpression(node, flags);
168 case ExpressionType.Quote:
169 EmitQuoteUnaryExpression(node);
171 case ExpressionType.RightShift:
172 EmitBinaryExpression(node, flags);
174 case ExpressionType.Subtract:
175 EmitBinaryExpression(node, flags);
177 case ExpressionType.SubtractChecked:
178 EmitBinaryExpression(node, flags);
180 case ExpressionType.TypeAs:
181 EmitUnaryExpression(node, flags);
183 case ExpressionType.TypeIs:
184 EmitTypeBinaryExpression(node);
186 case ExpressionType.Assign:
187 EmitAssignBinaryExpression(node);
189 case ExpressionType.Block:
190 EmitBlockExpression(node, flags);
192 case ExpressionType.DebugInfo:
193 EmitDebugInfoExpression(node);
195 case ExpressionType.Decrement:
196 EmitUnaryExpression(node, flags);
198 case ExpressionType.Dynamic:
199 EmitDynamicExpression(node);
201 case ExpressionType.Default:
202 EmitDefaultExpression(node);
204 case ExpressionType.Extension:
205 EmitExtensionExpression(node);
207 case ExpressionType.Goto:
208 EmitGotoExpression(node, flags);
210 case ExpressionType.Increment:
211 EmitUnaryExpression(node, flags);
213 case ExpressionType.Index:
214 EmitIndexExpression(node);
216 case ExpressionType.Label:
217 EmitLabelExpression(node, flags);
219 case ExpressionType.RuntimeVariables:
220 EmitRuntimeVariablesExpression(node);
222 case ExpressionType.Loop:
223 EmitLoopExpression(node);
225 case ExpressionType.Switch:
226 EmitSwitchExpression(node, flags);
228 case ExpressionType.Throw:
229 EmitThrowUnaryExpression(node);
231 case ExpressionType.Try:
232 EmitTryExpression(node);
234 case ExpressionType.Unbox:
235 EmitUnboxUnaryExpression(node);
237 case ExpressionType.TypeEqual:
238 EmitTypeBinaryExpression(node);
240 case ExpressionType.OnesComplement:
241 EmitUnaryExpression(node, flags);
243 case ExpressionType.IsTrue:
244 EmitUnaryExpression(node, flags);
246 case ExpressionType.IsFalse:
247 EmitUnaryExpression(node, flags);
250 // *** END GENERATED CODE ***
255 throw ContractUtils.Unreachable;
259 EmitExpressionEnd(startEmitted);
263 private static bool IsChecked(ExpressionType op) {
265 #region Generated Checked Operations
267 // *** BEGIN GENERATED CODE ***
268 // generated by function: gen_checked_ops from: generate_tree.py
270 case ExpressionType.AddChecked:
271 case ExpressionType.ConvertChecked:
272 case ExpressionType.MultiplyChecked:
273 case ExpressionType.NegateChecked:
274 case ExpressionType.SubtractChecked:
275 case ExpressionType.AddAssignChecked:
276 case ExpressionType.MultiplyAssignChecked:
277 case ExpressionType.SubtractAssignChecked:
279 // *** END GENERATED CODE ***