public void TestLdDec() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(decimal), Type.EmptyTypes); using (var il = new GroboIL(method)) { il.LdDec(-12.3m); il.LdDec(34.5m); il.Call(typeof(decimal).GetMethod("Add", new[] { typeof(decimal), typeof(decimal) })); il.Ret(); Console.WriteLine(il.GetILCode()); } var compiledMethod = (Func <decimal>)method.CreateDelegate(typeof(Func <decimal>)); Assert.That(compiledMethod(), Is.EqualTo(22.2m)); }
private static void EmitValue(GroboIL il, object value) { //value.GetType() is the "real" type, only all pointers are UIntPtr and nullables are BoxedNullable //It can be: //Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Enum, IntPtr, UIntPtr //Or their nullable equivalents //Or string switch (value) { case bool boolean: il.Ldc_I4(boolean ? 1 : 0); break; case char character: il.Ldc_I4(character); break; case sbyte int8: il.Ldc_I4(int8); break; case byte uint8: il.Ldc_I4(uint8); break; case short int16: il.Ldc_I4(int16); break; case ushort uint16: il.Ldc_I4(uint16); break; case int int32: il.Ldc_I4(int32); break; case uint uint32: il.Ldc_I4((int)uint32); break; case long int64: il.Ldc_I8(int64); break; case ulong uint64: il.Ldc_I8((long)uint64); break; case float float32: il.Ldc_R4(float32); break; case double float64: il.Ldc_R8(float64); break; case decimal decimal128: il.LdDec(decimal128); break; case DateTime dateTime: var local = il.DeclareLocal(typeof(DateTime)); il.Ldloca(local); il.Ldc_I8(dateTime.Ticks); il.Ldc_I4((int)dateTime.Kind); il.Call(typeof(DateTime).GetConstructor(new[] { typeof(long), typeof(DateTimeKind) })); il.Ldloc(local); break; case UIntPtr unint: il.Ldc_IntPtr(Unsafe.As <UIntPtr, IntPtr>(ref unint)); break; case IntPtr nint: il.Ldc_IntPtr(nint); break; case Enum enumeration: var underlyingType = Enum.GetUnderlyingType(enumeration.GetType()); var underlyingValue = Convert.ChangeType(enumeration, underlyingType); EmitValue(il, underlyingValue); break; case BoxedNullable boxedNullable: EmitValue(il, boxedNullable.UnderlyingValue); il.Newobj(boxedNullable.NullableType.GetConstructor(new[] { boxedNullable.UnderlyingType })); break; case string str: il.Ldstr(str); break; default: throw new ArgumentException($"Value {value} of type {value.GetType()} is not supported by the emitter."); } }