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