this.value = value;
}
+#if !FULL_AOT_RUNTIME
internal override void Emit (EmitContext ec)
{
- ILGenerator ig = ec.ig;
+ if (Type.IsNullable ()) {
+ EmitNullableConstant (ec, Type, value);
+ return;
+ }
+
+ EmitConstant (ec, Type, value);
+ }
- switch (Type.GetTypeCode (Type)){
+ void EmitNullableConstant (EmitContext ec, Type type, object value)
+ {
+ if (value == null) {
+ var local = ec.ig.DeclareLocal (type);
+ ec.EmitNullableInitialize (local);
+ } else {
+ EmitConstant (ec, type.GetFirstGenericArgument (), value);
+ ec.EmitNullableNew (type);
+ }
+ }
+
+ void EmitConstant (EmitContext ec, Type type, object value)
+ {
+ var ig = ec.ig;
+
+ switch (Type.GetTypeCode (type)){
case TypeCode.Byte:
ig.Emit (OpCodes.Ldc_I4, (int) ((byte)value));
return;
ig.Emit (OpCodes.Newobj, typeof (Decimal).GetConstructor (new Type [5] { ti, ti, ti, typeof(bool), typeof(byte) }));
return;
- }
+ }
+
+ case TypeCode.DateTime: {
+ var date = (DateTime) value;
+ var local = ig.DeclareLocal (typeof (DateTime));
+
+ ig.Emit (OpCodes.Ldloca, local);
+ ig.Emit (OpCodes.Ldc_I8, date.Ticks);
+ ig.Emit (OpCodes.Ldc_I4, (int) date.Kind);
+ ig.Emit (OpCodes.Call, typeof (DateTime).GetConstructor (new [] { typeof (long), typeof (DateTimeKind) }));
+ ig.Emit (OpCodes.Ldloc, local);
+
+ return;
+ }
+
+ case TypeCode.DBNull:
+ ig.Emit (OpCodes.Ldsfld, typeof (DBNull).GetField ("Value", BindingFlags.Public | BindingFlags.Static));
+ return;
case TypeCode.String:
- ig.Emit (OpCodes.Ldstr, (string) value);
+ EmitIfNotNull (ec, c => c.ig.Emit (OpCodes.Ldstr, (string) value));
return;
case TypeCode.Object:
- break;
+ EmitIfNotNull (ec, c => c.EmitReadGlobal (value));
+ return;
}
throw new NotImplementedException (String.Format ("No support for constants of type {0} yet", Type));
}
+
+ void EmitIfNotNull (EmitContext ec, Action<EmitContext> emit)
+ {
+ if (value == null) {
+ ec.ig.Emit (OpCodes.Ldnull);
+ return;
+ }
+
+ emit (ec);
+ }
+#endif
}
}