void EmitLoadLiteral(IType type, long l)
{
if (type.IsEnum)
type = TypeSystemServices.Map(GetEnumUnderlyingType(type));
if (!(IsInteger(type) || type == TypeSystemServices.CharType))
throw new InvalidOperationException();
var needsLongConv = true;
switch (l)
{
case -1L:
{
if (IsLong(type) || type == TypeSystemServices.ULongType)
{
_il.Emit(OpCodes.Ldc_I8, -1L);
needsLongConv = false;
}
else
_il.Emit(OpCodes.Ldc_I4_M1);
}
break;
case 0L:
_il.Emit(OpCodes.Ldc_I4_0);
break;
case 1L:
_il.Emit(OpCodes.Ldc_I4_1);
break;
case 2L:
_il.Emit(OpCodes.Ldc_I4_2);
break;
case 3L:
_il.Emit(OpCodes.Ldc_I4_3);
break;
case 4L:
_il.Emit(OpCodes.Ldc_I4_4);
break;
case 5L:
_il.Emit(OpCodes.Ldc_I4_5);
break;
case 6L:
_il.Emit(OpCodes.Ldc_I4_6);
break;
case 7L:
_il.Emit(OpCodes.Ldc_I4_7);
break;
case 8L:
_il.Emit(OpCodes.Ldc_I4_8);
break;
default:
{
if (IsLong(type))
{
_il.Emit(OpCodes.Ldc_I8, l);
return;
}
if (l == (sbyte) l) //fits in an signed i1
{
_il.Emit(OpCodes.Ldc_I4_S, (sbyte) l);
}
else if (l == (int) l || l == (uint) l) //fits in an i4
{
if ((int) l == -1)
_il.Emit(OpCodes.Ldc_I4_M1);
else
_il.Emit(OpCodes.Ldc_I4, (int) l);
}
else
{
_il.Emit(OpCodes.Ldc_I8, l);
needsLongConv = false;
}
}
break;
}
if (needsLongConv && IsLong(type))
_il.Emit(OpCodes.Conv_I8);
else if (type == TypeSystemServices.ULongType)
_il.Emit(OpCodes.Conv_U8);
}