Files
2026-06-04 11:42:34 +02:00

826 lines
24 KiB
C#

using System;
using System.Reflection;
using System.Reflection.Emit;
namespace System.Linq.Expressions
{
/// <summary>Represents an expression that has a binary operator.</summary>
// Token: 0x02000015 RID: 21
public sealed class BinaryExpression : Expression
{
// Token: 0x06000131 RID: 305 RVA: 0x000077B4 File Offset: 0x000059B4
internal BinaryExpression(ExpressionType node_type, Type type, Expression left, Expression right)
: base(node_type, type)
{
this.left = left;
this.right = right;
}
// Token: 0x06000132 RID: 306 RVA: 0x000077D0 File Offset: 0x000059D0
internal BinaryExpression(ExpressionType node_type, Type type, Expression left, Expression right, MethodInfo method)
: base(node_type, type)
{
this.left = left;
this.right = right;
this.method = method;
}
// Token: 0x06000133 RID: 307 RVA: 0x000077F4 File Offset: 0x000059F4
internal BinaryExpression(ExpressionType node_type, Type type, Expression left, Expression right, bool lift_to_null, bool is_lifted, MethodInfo method, LambdaExpression conversion)
: base(node_type, type)
{
this.left = left;
this.right = right;
this.method = method;
this.conversion = conversion;
this.lift_to_null = lift_to_null;
this.is_lifted = is_lifted;
}
/// <summary>Gets the left operand of the binary operation.</summary>
/// <returns>An <see cref="T:System.Linq.Expressions.Expression" /> that represents the left operand of the binary operation.</returns>
// Token: 0x17000011 RID: 17
// (get) Token: 0x06000134 RID: 308 RVA: 0x00007830 File Offset: 0x00005A30
public Expression Left
{
get
{
return this.left;
}
}
/// <summary>Gets the right operand of the binary operation.</summary>
/// <returns>An <see cref="T:System.Linq.Expressions.Expression" /> that represents the right operand of the binary operation.</returns>
// Token: 0x17000012 RID: 18
// (get) Token: 0x06000135 RID: 309 RVA: 0x00007838 File Offset: 0x00005A38
public Expression Right
{
get
{
return this.right;
}
}
/// <summary>Gets the implementing method for the binary operation.</summary>
/// <returns>The <see cref="T:System.Reflection.MethodInfo" /> that represents the implementing method.</returns>
// Token: 0x17000013 RID: 19
// (get) Token: 0x06000136 RID: 310 RVA: 0x00007840 File Offset: 0x00005A40
public MethodInfo Method
{
get
{
return this.method;
}
}
/// <summary>Gets a value that indicates whether the expression tree node represents a lifted call to an operator.</summary>
/// <returns>true if the node represents a lifted call; otherwise, false.</returns>
// Token: 0x17000014 RID: 20
// (get) Token: 0x06000137 RID: 311 RVA: 0x00007848 File Offset: 0x00005A48
public bool IsLifted
{
get
{
return this.is_lifted;
}
}
/// <summary>Gets a value that indicates whether the expression tree node represents a lifted call to an operator whose return type is lifted to a nullable type.</summary>
/// <returns>true if the operator's return type is lifted to a nullable type; otherwise, false.</returns>
// Token: 0x17000015 RID: 21
// (get) Token: 0x06000138 RID: 312 RVA: 0x00007850 File Offset: 0x00005A50
public bool IsLiftedToNull
{
get
{
return this.lift_to_null;
}
}
/// <summary>Gets the type conversion function that is used by a coalescing operation.</summary>
/// <returns>A <see cref="T:System.Linq.Expressions.LambdaExpression" /> that represents a type conversion function.</returns>
// Token: 0x17000016 RID: 22
// (get) Token: 0x06000139 RID: 313 RVA: 0x00007858 File Offset: 0x00005A58
public LambdaExpression Conversion
{
get
{
return this.conversion;
}
}
// Token: 0x0600013A RID: 314 RVA: 0x00007860 File Offset: 0x00005A60
private void EmitArrayAccess(EmitContext ec)
{
this.left.Emit(ec);
this.right.Emit(ec);
ec.ig.Emit(OpCodes.Ldelem, base.Type);
}
// Token: 0x0600013B RID: 315 RVA: 0x0000789C File Offset: 0x00005A9C
private void EmitLogicalBinary(EmitContext ec)
{
ExpressionType nodeType = base.NodeType;
if (nodeType != ExpressionType.And)
{
if (nodeType != ExpressionType.AndAlso)
{
if (nodeType == ExpressionType.Or)
{
goto IL_2A;
}
if (nodeType != ExpressionType.OrElse)
{
return;
}
}
if (!this.IsLifted)
{
this.EmitLogicalShortCircuit(ec);
}
else
{
this.EmitLiftedLogicalShortCircuit(ec);
}
return;
}
IL_2A:
if (!this.IsLifted)
{
this.EmitLogical(ec);
}
else if (base.Type == typeof(bool?))
{
this.EmitLiftedLogical(ec);
}
else
{
this.EmitLiftedArithmeticBinary(ec);
}
}
// Token: 0x0600013C RID: 316 RVA: 0x0000793C File Offset: 0x00005B3C
private void EmitLogical(EmitContext ec)
{
this.EmitNonLiftedBinary(ec);
}
// Token: 0x0600013D RID: 317 RVA: 0x00007948 File Offset: 0x00005B48
private void EmitLiftedLogical(EmitContext ec)
{
ILGenerator ig = ec.ig;
bool flag = base.NodeType == ExpressionType.And;
LocalBuilder localBuilder = ec.EmitStored(this.left);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
Label label3 = ig.DefineLabel();
ec.EmitNullableGetValueOrDefault(localBuilder);
ig.Emit(OpCodes.Brtrue, label);
ec.EmitNullableGetValueOrDefault(localBuilder2);
ig.Emit(OpCodes.Brtrue, label2);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, label);
ig.MarkLabel(label2);
ec.EmitLoad((!flag) ? localBuilder2 : localBuilder);
ig.Emit(OpCodes.Br, label3);
ig.MarkLabel(label);
ec.EmitLoad((!flag) ? localBuilder : localBuilder2);
ig.MarkLabel(label3);
}
// Token: 0x0600013E RID: 318 RVA: 0x00007A20 File Offset: 0x00005C20
private void EmitLogicalShortCircuit(EmitContext ec)
{
ILGenerator ig = ec.ig;
bool flag = base.NodeType == ExpressionType.AndAlso;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
ec.Emit(this.left);
ig.Emit((!flag) ? OpCodes.Brtrue : OpCodes.Brfalse, label);
ec.Emit(this.right);
ig.Emit(OpCodes.Br, label2);
ig.MarkLabel(label);
ig.Emit((!flag) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
ig.MarkLabel(label2);
}
// Token: 0x0600013F RID: 319 RVA: 0x00007AB8 File Offset: 0x00005CB8
private MethodInfo GetFalseOperator()
{
return Expression.GetFalseOperator(this.left.Type.GetNotNullableType());
}
// Token: 0x06000140 RID: 320 RVA: 0x00007AD0 File Offset: 0x00005CD0
private MethodInfo GetTrueOperator()
{
return Expression.GetTrueOperator(this.left.Type.GetNotNullableType());
}
// Token: 0x06000141 RID: 321 RVA: 0x00007AE8 File Offset: 0x00005CE8
private void EmitUserDefinedLogicalShortCircuit(EmitContext ec)
{
ILGenerator ig = ec.ig;
bool flag = base.NodeType == ExpressionType.AndAlso;
Label label = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
ec.EmitLoad(localBuilder);
ig.Emit(OpCodes.Dup);
ec.EmitCall((!flag) ? this.GetTrueOperator() : this.GetFalseOperator());
ig.Emit(OpCodes.Brtrue, label);
ec.Emit(this.right);
ec.EmitCall(this.method);
ig.MarkLabel(label);
}
// Token: 0x06000142 RID: 322 RVA: 0x00007B74 File Offset: 0x00005D74
private void EmitLiftedLogicalShortCircuit(EmitContext ec)
{
ILGenerator ig = ec.ig;
bool flag = base.NodeType == ExpressionType.AndAlso;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
Label label3 = ig.DefineLabel();
Label label4 = ig.DefineLabel();
Label label5 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, label);
ec.EmitNullableGetValueOrDefault(localBuilder);
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Ceq);
ig.Emit((!flag) ? OpCodes.Brfalse : OpCodes.Brtrue, label2);
ig.MarkLabel(label);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
ec.EmitNullableHasValue(localBuilder2);
ig.Emit(OpCodes.Brfalse_S, label3);
ec.EmitNullableGetValueOrDefault(localBuilder2);
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Ceq);
ig.Emit((!flag) ? OpCodes.Brfalse : OpCodes.Brtrue, label2);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, label3);
ig.Emit((!flag) ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
ig.Emit(OpCodes.Br_S, label4);
ig.MarkLabel(label2);
ig.Emit((!flag) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
ig.MarkLabel(label4);
ec.EmitNullableNew(base.Type);
ig.Emit(OpCodes.Br, label5);
ig.MarkLabel(label3);
LocalBuilder localBuilder3 = ig.DeclareLocal(base.Type);
ec.EmitNullableInitialize(localBuilder3);
ig.MarkLabel(label5);
}
// Token: 0x06000143 RID: 323 RVA: 0x00007D20 File Offset: 0x00005F20
private void EmitCoalesce(EmitContext ec)
{
ILGenerator ig = ec.ig;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
bool flag = localBuilder.LocalType.IsNullable();
if (flag)
{
ec.EmitNullableHasValue(localBuilder);
}
else
{
ec.EmitLoad(localBuilder);
}
ig.Emit(OpCodes.Brfalse, label2);
if (flag && !base.Type.IsNullable())
{
ec.EmitNullableGetValue(localBuilder);
}
else
{
ec.EmitLoad(localBuilder);
}
ig.Emit(OpCodes.Br, label);
ig.MarkLabel(label2);
ec.Emit(this.right);
ig.MarkLabel(label);
}
// Token: 0x06000144 RID: 324 RVA: 0x00007DD4 File Offset: 0x00005FD4
private void EmitConvertedCoalesce(EmitContext ec)
{
ILGenerator ig = ec.ig;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
if (localBuilder.LocalType.IsNullable())
{
ec.EmitNullableHasValue(localBuilder);
}
else
{
ec.EmitLoad(localBuilder);
}
ig.Emit(OpCodes.Brfalse, label2);
ec.Emit(this.conversion);
ec.EmitLoad(localBuilder);
ig.Emit(OpCodes.Callvirt, this.conversion.Type.GetInvokeMethod());
ig.Emit(OpCodes.Br, label);
ig.MarkLabel(label2);
ec.Emit(this.right);
ig.MarkLabel(label);
}
// Token: 0x06000145 RID: 325 RVA: 0x00007E88 File Offset: 0x00006088
private static bool IsInt32OrInt64(Type type)
{
return type == typeof(int) || type == typeof(long);
}
// Token: 0x06000146 RID: 326 RVA: 0x00007EB8 File Offset: 0x000060B8
private static bool IsSingleOrDouble(Type type)
{
return type == typeof(float) || type == typeof(double);
}
// Token: 0x06000147 RID: 327 RVA: 0x00007EE8 File Offset: 0x000060E8
private void EmitBinaryOperator(EmitContext ec)
{
ILGenerator ig = ec.ig;
bool flag = Expression.IsUnsigned(this.left.Type);
ExpressionType nodeType = base.NodeType;
switch (nodeType)
{
case ExpressionType.Divide:
ig.Emit((!flag) ? OpCodes.Div : OpCodes.Div_Un);
break;
case ExpressionType.Equal:
ig.Emit(OpCodes.Ceq);
break;
case ExpressionType.ExclusiveOr:
ig.Emit(OpCodes.Xor);
break;
case ExpressionType.GreaterThan:
ig.Emit((!flag) ? OpCodes.Cgt : OpCodes.Cgt_Un);
break;
case ExpressionType.GreaterThanOrEqual:
if (flag || BinaryExpression.IsSingleOrDouble(this.left.Type))
{
ig.Emit(OpCodes.Clt_Un);
}
else
{
ig.Emit(OpCodes.Clt);
}
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Ceq);
break;
default:
switch (nodeType)
{
case ExpressionType.Add:
ig.Emit(OpCodes.Add);
break;
case ExpressionType.AddChecked:
if (BinaryExpression.IsInt32OrInt64(this.left.Type))
{
ig.Emit(OpCodes.Add_Ovf);
}
else
{
ig.Emit((!flag) ? OpCodes.Add : OpCodes.Add_Ovf_Un);
}
break;
case ExpressionType.And:
ig.Emit(OpCodes.And);
break;
default:
throw new InvalidOperationException(string.Format("Internal error: BinaryExpression contains non-Binary nodetype {0}", base.NodeType));
}
break;
case ExpressionType.LeftShift:
case ExpressionType.RightShift:
ig.Emit(OpCodes.Ldc_I4, (this.left.Type != typeof(int)) ? 63 : 31);
ig.Emit(OpCodes.And);
if (base.NodeType == ExpressionType.RightShift)
{
ig.Emit((!flag) ? OpCodes.Shr : OpCodes.Shr_Un);
}
else
{
ig.Emit(OpCodes.Shl);
}
break;
case ExpressionType.LessThan:
ig.Emit((!flag) ? OpCodes.Clt : OpCodes.Clt_Un);
break;
case ExpressionType.LessThanOrEqual:
if (flag || BinaryExpression.IsSingleOrDouble(this.left.Type))
{
ig.Emit(OpCodes.Cgt_Un);
}
else
{
ig.Emit(OpCodes.Cgt);
}
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Ceq);
break;
case ExpressionType.Modulo:
ig.Emit((!flag) ? OpCodes.Rem : OpCodes.Rem_Un);
break;
case ExpressionType.Multiply:
ig.Emit(OpCodes.Mul);
break;
case ExpressionType.MultiplyChecked:
if (BinaryExpression.IsInt32OrInt64(this.left.Type))
{
ig.Emit(OpCodes.Mul_Ovf);
}
else
{
ig.Emit((!flag) ? OpCodes.Mul : OpCodes.Mul_Ovf_Un);
}
break;
case ExpressionType.NotEqual:
ig.Emit(OpCodes.Ceq);
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Ceq);
break;
case ExpressionType.Or:
ig.Emit(OpCodes.Or);
break;
case ExpressionType.Power:
ig.Emit(OpCodes.Call, typeof(Math).GetMethod("Pow"));
break;
case ExpressionType.Subtract:
ig.Emit(OpCodes.Sub);
break;
case ExpressionType.SubtractChecked:
if (BinaryExpression.IsInt32OrInt64(this.left.Type))
{
ig.Emit(OpCodes.Sub_Ovf);
}
else
{
ig.Emit((!flag) ? OpCodes.Sub : OpCodes.Sub_Ovf_Un);
}
break;
}
}
// Token: 0x06000148 RID: 328 RVA: 0x000082F0 File Offset: 0x000064F0
private bool IsLeftLiftedBinary()
{
return this.left.Type.IsNullable() && !this.right.Type.IsNullable();
}
// Token: 0x06000149 RID: 329 RVA: 0x00008328 File Offset: 0x00006528
private void EmitLeftLiftedToNullBinary(EmitContext ec)
{
ILGenerator ig = ec.ig;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, label);
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.Emit(this.right);
this.EmitBinaryOperator(ec);
ec.EmitNullableNew(base.Type);
ig.Emit(OpCodes.Br, label2);
ig.MarkLabel(label);
LocalBuilder localBuilder2 = ig.DeclareLocal(base.Type);
ec.EmitNullableInitialize(localBuilder2);
ig.MarkLabel(label2);
}
// Token: 0x0600014A RID: 330 RVA: 0x000083C0 File Offset: 0x000065C0
private void EmitLiftedArithmeticBinary(EmitContext ec)
{
if (this.IsLeftLiftedBinary())
{
this.EmitLeftLiftedToNullBinary(ec);
}
else
{
this.EmitLiftedToNullBinary(ec);
}
}
// Token: 0x0600014B RID: 331 RVA: 0x000083E0 File Offset: 0x000065E0
private void EmitLiftedToNullBinary(EmitContext ec)
{
ILGenerator ig = ec.ig;
LocalBuilder localBuilder = ec.EmitStored(this.left);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
LocalBuilder localBuilder3 = ig.DeclareLocal(base.Type);
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
ec.EmitNullableHasValue(localBuilder);
ec.EmitNullableHasValue(localBuilder2);
ig.Emit(OpCodes.And);
ig.Emit(OpCodes.Brtrue, label);
ec.EmitNullableInitialize(localBuilder3);
ig.Emit(OpCodes.Br, label2);
ig.MarkLabel(label);
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.EmitNullableGetValueOrDefault(localBuilder2);
this.EmitBinaryOperator(ec);
ec.EmitNullableNew(localBuilder3.LocalType);
ig.MarkLabel(label2);
}
// Token: 0x0600014C RID: 332 RVA: 0x00008498 File Offset: 0x00006698
private void EmitLiftedRelationalBinary(EmitContext ec)
{
ILGenerator ig = ec.ig;
LocalBuilder localBuilder = ec.EmitStored(this.left);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.EmitNullableGetValueOrDefault(localBuilder2);
ExpressionType expressionType = base.NodeType;
if (expressionType != ExpressionType.Equal && expressionType != ExpressionType.NotEqual)
{
this.EmitBinaryOperator(ec);
ig.Emit(OpCodes.Brfalse, label);
}
else
{
ig.Emit(OpCodes.Bne_Un, label);
}
ec.EmitNullableHasValue(localBuilder);
ec.EmitNullableHasValue(localBuilder2);
expressionType = base.NodeType;
if (expressionType != ExpressionType.Equal)
{
if (expressionType != ExpressionType.NotEqual)
{
ig.Emit(OpCodes.And);
}
else
{
ig.Emit(OpCodes.Ceq);
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Ceq);
}
}
else
{
ig.Emit(OpCodes.Ceq);
}
ig.Emit(OpCodes.Br, label2);
ig.MarkLabel(label);
ig.Emit((base.NodeType != ExpressionType.NotEqual) ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1);
ig.MarkLabel(label2);
}
// Token: 0x0600014D RID: 333 RVA: 0x000085DC File Offset: 0x000067DC
private void EmitArithmeticBinary(EmitContext ec)
{
if (!this.IsLifted)
{
this.EmitNonLiftedBinary(ec);
}
else
{
this.EmitLiftedArithmeticBinary(ec);
}
}
// Token: 0x0600014E RID: 334 RVA: 0x000085FC File Offset: 0x000067FC
private void EmitNonLiftedBinary(EmitContext ec)
{
ec.Emit(this.left);
ec.Emit(this.right);
this.EmitBinaryOperator(ec);
}
// Token: 0x0600014F RID: 335 RVA: 0x00008620 File Offset: 0x00006820
private void EmitRelationalBinary(EmitContext ec)
{
if (!this.IsLifted)
{
this.EmitNonLiftedBinary(ec);
}
else if (this.IsLiftedToNull)
{
this.EmitLiftedToNullBinary(ec);
}
else
{
this.EmitLiftedRelationalBinary(ec);
}
}
// Token: 0x06000150 RID: 336 RVA: 0x00008664 File Offset: 0x00006864
private void EmitLiftedUserDefinedOperator(EmitContext ec)
{
ILGenerator ig = ec.ig;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
Label label3 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
ec.EmitNullableHasValue(localBuilder);
ec.EmitNullableHasValue(localBuilder2);
ExpressionType nodeType = base.NodeType;
if (nodeType != ExpressionType.Equal)
{
if (nodeType != ExpressionType.NotEqual)
{
ig.Emit(OpCodes.And);
ig.Emit(OpCodes.Brfalse, label2);
}
else
{
ig.Emit(OpCodes.Bne_Un, label);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, label2);
}
}
else
{
ig.Emit(OpCodes.Bne_Un, label2);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, label);
}
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.EmitNullableGetValueOrDefault(localBuilder2);
ec.EmitCall(this.method);
ig.Emit(OpCodes.Br, label3);
ig.MarkLabel(label);
ig.Emit(OpCodes.Ldc_I4_1);
ig.Emit(OpCodes.Br, label3);
ig.MarkLabel(label2);
ig.Emit(OpCodes.Ldc_I4_0);
ig.Emit(OpCodes.Br, label3);
ig.MarkLabel(label3);
}
// Token: 0x06000151 RID: 337 RVA: 0x000087AC File Offset: 0x000069AC
private void EmitLiftedToNullUserDefinedOperator(EmitContext ec)
{
ILGenerator ig = ec.ig;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
ec.EmitNullableHasValue(localBuilder);
ec.EmitNullableHasValue(localBuilder2);
ig.Emit(OpCodes.And);
ig.Emit(OpCodes.Brfalse, label);
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.EmitNullableGetValueOrDefault(localBuilder2);
ec.EmitCall(this.method);
ec.EmitNullableNew(base.Type);
ig.Emit(OpCodes.Br, label2);
ig.MarkLabel(label);
LocalBuilder localBuilder3 = ig.DeclareLocal(base.Type);
ec.EmitNullableInitialize(localBuilder3);
ig.MarkLabel(label2);
}
// Token: 0x06000152 RID: 338 RVA: 0x00008868 File Offset: 0x00006A68
private void EmitUserDefinedLiftedLogicalShortCircuit(EmitContext ec)
{
ILGenerator ig = ec.ig;
bool flag = base.NodeType == ExpressionType.AndAlso;
Label label = ig.DefineLabel();
Label label2 = ig.DefineLabel();
Label label3 = ig.DefineLabel();
Label label4 = ig.DefineLabel();
LocalBuilder localBuilder = ec.EmitStored(this.left);
ec.EmitNullableHasValue(localBuilder);
ig.Emit(OpCodes.Brfalse, (!flag) ? label : label3);
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.EmitCall((!flag) ? this.GetTrueOperator() : this.GetFalseOperator());
ig.Emit(OpCodes.Brtrue, label2);
ig.MarkLabel(label);
LocalBuilder localBuilder2 = ec.EmitStored(this.right);
ec.EmitNullableHasValue(localBuilder2);
ig.Emit(OpCodes.Brfalse, label3);
ec.EmitNullableGetValueOrDefault(localBuilder);
ec.EmitNullableGetValueOrDefault(localBuilder2);
ec.EmitCall(this.method);
ec.EmitNullableNew(base.Type);
ig.Emit(OpCodes.Br, label4);
ig.MarkLabel(label2);
ec.EmitLoad(localBuilder);
ig.Emit(OpCodes.Br, label4);
ig.MarkLabel(label3);
LocalBuilder localBuilder3 = ig.DeclareLocal(base.Type);
ec.EmitNullableInitialize(localBuilder3);
ig.MarkLabel(label4);
}
// Token: 0x06000153 RID: 339 RVA: 0x000089A8 File Offset: 0x00006BA8
private void EmitUserDefinedOperator(EmitContext ec)
{
if (!this.IsLifted)
{
ExpressionType expressionType = base.NodeType;
if (expressionType != ExpressionType.AndAlso && expressionType != ExpressionType.OrElse)
{
this.left.Emit(ec);
this.right.Emit(ec);
ec.EmitCall(this.method);
}
else
{
this.EmitUserDefinedLogicalShortCircuit(ec);
}
}
else if (this.IsLiftedToNull)
{
ExpressionType expressionType = base.NodeType;
if (expressionType != ExpressionType.AndAlso && expressionType != ExpressionType.OrElse)
{
this.EmitLiftedToNullUserDefinedOperator(ec);
}
else
{
this.EmitUserDefinedLiftedLogicalShortCircuit(ec);
}
}
else
{
this.EmitLiftedUserDefinedOperator(ec);
}
}
// Token: 0x06000154 RID: 340 RVA: 0x00008A60 File Offset: 0x00006C60
internal override void Emit(EmitContext ec)
{
if (this.method != null)
{
this.EmitUserDefinedOperator(ec);
return;
}
switch (base.NodeType)
{
case ExpressionType.Add:
case ExpressionType.AddChecked:
case ExpressionType.Divide:
case ExpressionType.ExclusiveOr:
case ExpressionType.LeftShift:
case ExpressionType.Modulo:
case ExpressionType.Multiply:
case ExpressionType.MultiplyChecked:
case ExpressionType.Power:
case ExpressionType.RightShift:
case ExpressionType.Subtract:
case ExpressionType.SubtractChecked:
this.EmitArithmeticBinary(ec);
return;
case ExpressionType.And:
case ExpressionType.AndAlso:
case ExpressionType.Or:
case ExpressionType.OrElse:
this.EmitLogicalBinary(ec);
return;
case ExpressionType.ArrayIndex:
this.EmitArrayAccess(ec);
return;
case ExpressionType.Coalesce:
if (this.conversion != null)
{
this.EmitConvertedCoalesce(ec);
}
else
{
this.EmitCoalesce(ec);
}
return;
case ExpressionType.Equal:
case ExpressionType.GreaterThan:
case ExpressionType.GreaterThanOrEqual:
case ExpressionType.LessThan:
case ExpressionType.LessThanOrEqual:
case ExpressionType.NotEqual:
this.EmitRelationalBinary(ec);
return;
}
throw new NotSupportedException(base.NodeType.ToString());
}
// Token: 0x04000058 RID: 88
private Expression left;
// Token: 0x04000059 RID: 89
private Expression right;
// Token: 0x0400005A RID: 90
private LambdaExpression conversion;
// Token: 0x0400005B RID: 91
private MethodInfo method;
// Token: 0x0400005C RID: 92
private bool lift_to_null;
// Token: 0x0400005D RID: 93
private bool is_lifted;
}
}