using System;
using System.Reflection;
using System.Reflection.Emit;
namespace System.Linq.Expressions
{
/// Represents an expression that has a constant value.
// Token: 0x02000017 RID: 23
public sealed class ConstantExpression : Expression
{
// Token: 0x0600015A RID: 346 RVA: 0x00008C4C File Offset: 0x00006E4C
internal ConstantExpression(object value, Type type)
: base(ExpressionType.Constant, type)
{
this.value = value;
}
/// Gets the value of the constant expression.
/// An equal to the value of the represented expression.
// Token: 0x1700001A RID: 26
// (get) Token: 0x0600015B RID: 347 RVA: 0x00008C60 File Offset: 0x00006E60
public object Value
{
get
{
return this.value;
}
}
// Token: 0x0600015C RID: 348 RVA: 0x00008C68 File Offset: 0x00006E68
internal override void Emit(EmitContext ec)
{
if (base.Type.IsNullable())
{
this.EmitNullableConstant(ec, base.Type, this.value);
return;
}
this.EmitConstant(ec, base.Type, this.value);
}
// Token: 0x0600015D RID: 349 RVA: 0x00008CAC File Offset: 0x00006EAC
private void EmitNullableConstant(EmitContext ec, Type type, object value)
{
if (value == null)
{
ILGenerator ig = ec.ig;
LocalBuilder localBuilder = ig.DeclareLocal(type);
ig.Emit(OpCodes.Ldloca, localBuilder);
ig.Emit(OpCodes.Initobj, type);
ig.Emit(OpCodes.Ldloc, localBuilder);
}
else
{
this.EmitConstant(ec, type.GetFirstGenericArgument(), value);
ec.EmitNullableNew(type);
}
}
// Token: 0x0600015E RID: 350 RVA: 0x00008D0C File Offset: 0x00006F0C
private void EmitConstant(EmitContext ec, Type type, object value)
{
ILGenerator ig = ec.ig;
switch (Type.GetTypeCode(type))
{
case TypeCode.Object:
this.EmitIfNotNull(ec, delegate(EmitContext c)
{
c.EmitReadGlobal(value);
});
return;
case TypeCode.DBNull:
ig.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField("Value", BindingFlags.Static | BindingFlags.Public));
return;
case TypeCode.Boolean:
if ((bool)this.Value)
{
ig.Emit(OpCodes.Ldc_I4_1);
}
else
{
ec.ig.Emit(OpCodes.Ldc_I4_0);
}
return;
case TypeCode.Char:
ig.Emit(OpCodes.Ldc_I4, (int)((char)value));
return;
case TypeCode.SByte:
ig.Emit(OpCodes.Ldc_I4, (int)((sbyte)value));
return;
case TypeCode.Byte:
ig.Emit(OpCodes.Ldc_I4, (int)((byte)value));
return;
case TypeCode.Int16:
ig.Emit(OpCodes.Ldc_I4, (int)((short)value));
return;
case TypeCode.UInt16:
ig.Emit(OpCodes.Ldc_I4, (int)((ushort)value));
return;
case TypeCode.Int32:
ig.Emit(OpCodes.Ldc_I4, (int)value);
return;
case TypeCode.UInt32:
ig.Emit(OpCodes.Ldc_I4, (int)((uint)this.Value));
return;
case TypeCode.Int64:
ig.Emit(OpCodes.Ldc_I8, (long)value);
return;
case TypeCode.UInt64:
ig.Emit(OpCodes.Ldc_I8, (long)((ulong)value));
return;
case TypeCode.Single:
ig.Emit(OpCodes.Ldc_R4, (float)value);
return;
case TypeCode.Double:
ig.Emit(OpCodes.Ldc_R8, (double)value);
return;
case TypeCode.Decimal:
{
decimal num = (decimal)value;
int[] bits = decimal.GetBits(num);
int num2 = (bits[3] >> 16) & 255;
Type typeFromHandle = typeof(int);
if (num2 == 0 && num <= 2147483647m && num >= -2147483648m)
{
ig.Emit(OpCodes.Ldc_I4, (int)num);
ig.Emit(OpCodes.Newobj, typeof(decimal).GetConstructor(new Type[] { typeFromHandle }));
return;
}
ig.Emit(OpCodes.Ldc_I4, bits[0]);
ig.Emit(OpCodes.Ldc_I4, bits[1]);
ig.Emit(OpCodes.Ldc_I4, bits[2]);
ig.Emit(OpCodes.Ldc_I4, bits[3] >> 31);
ig.Emit(OpCodes.Ldc_I4, num2);
ig.Emit(OpCodes.Newobj, typeof(decimal).GetConstructor(new Type[]
{
typeFromHandle,
typeFromHandle,
typeFromHandle,
typeof(bool),
typeof(byte)
}));
return;
}
case TypeCode.DateTime:
{
DateTime dateTime = (DateTime)value;
LocalBuilder localBuilder = ig.DeclareLocal(typeof(DateTime));
ig.Emit(OpCodes.Ldloca, localBuilder);
ig.Emit(OpCodes.Ldc_I8, dateTime.Ticks);
ig.Emit(OpCodes.Ldc_I4, (int)dateTime.Kind);
ig.Emit(OpCodes.Call, typeof(DateTime).GetConstructor(new Type[]
{
typeof(long),
typeof(DateTimeKind)
}));
ig.Emit(OpCodes.Ldloc, localBuilder);
return;
}
case TypeCode.String:
this.EmitIfNotNull(ec, delegate(EmitContext c)
{
c.ig.Emit(OpCodes.Ldstr, (string)value);
});
return;
}
throw new NotImplementedException(string.Format("No support for constants of type {0} yet", base.Type));
}
// Token: 0x0600015F RID: 351 RVA: 0x000090E8 File Offset: 0x000072E8
private void EmitIfNotNull(EmitContext ec, Action emit)
{
if (this.value == null)
{
ec.ig.Emit(OpCodes.Ldnull);
return;
}
emit(ec);
}
// Token: 0x04000061 RID: 97
private object value;
}
}