private Func <TestClassA, int> Build1() { var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public); var method = typeBuilder.DefineMethod("zzz", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(TestClassA) }); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Ldfld(typeof(TestClassA).GetField("Y")); var y = il.DeclareLocal(typeof(int)); il.Stloc(y); il.Ldarg(0); il.Ldfld(typeof(TestClassA).GetField("Z")); var z = il.DeclareLocal(typeof(int)); il.Stloc(z); il.Ldloc(y); il.Ldloc(z); il.Add(); il.Ret(); } var type = typeBuilder.CreateType(); var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(Func <TestClassA, int>), Type.EmptyTypes, Module, true); using (var il = new GroboIL(dynamicMethod)) { il.Ldnull(); il.Ldftn(type.GetMethod("zzz")); il.Newobj(typeof(Func <TestClassA, int>).GetConstructor(new[] { typeof(object), typeof(IntPtr) })); il.Ret(); } return(((Func <Func <TestClassA, int> >)dynamicMethod.CreateDelegate(typeof(Func <Func <TestClassA, int> >)))()); }
private static Func <IntPtr, long, long> EmitRelJmpHooker() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(long), new[] { typeof(IntPtr), typeof(long) }, typeof(string), true); using (var il = new GroboIL(method)) { il.VerificationKind = TypesAssignabilityVerificationKind.LowLevelOnly; var cycleLabel = il.DefineLabel("cycle"); il.MarkLabel(cycleLabel); il.Ldarg(0); // stack: [ptr] il.Dup(); // stack: [ptr, ptr] var x = il.DeclareLocal(typeof(long)); il.Ldind(typeof(long)); // stack: [ptr, *ptr] il.Dup(); il.Stloc(x); // x = *ptr; stack: [ptr, newCode] il.Ldc_I8(unchecked ((long)0xFFFFFF0000000000)); il.And(); // stack: [ptr, x & 0xFFFFFF0000000000] il.Ldarg(1); // stack: [ptr, x & 0xFFFFFF0000000000, code] il.Or(); // stack: [ptr, (x & 0xFFFFFF0000000000) | code] il.Ldloc(x); // stack: [ptr, (x & 0xFFFFFF0000000000) | code, newCode] var methodInfo = typeof(Interlocked).GetMethod("CompareExchange", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(long).MakeByRefType(), typeof(long), typeof(long) }, null); il.Call(methodInfo); // stack: [Interlocked.CompareExchange(ptr, (x & 0xFFFFFF0000000000) | code, newCode)] il.Ldloc(x); // stack: [Interlocked.CompareExchange(ptr, (x & 0xFFFFFF0000000000) | code, newCode), newCode] il.Bne_Un(cycleLabel); // if(Interlocked.CompareExchange(ptr, (x & 0xFFFFFF0000000000) | code, newCode) != newCode) goto cycle; stack: [] il.Ldloc(x); il.Ret(); } return((Func <IntPtr, long, long>)method.CreateDelegate(typeof(Func <IntPtr, long, long>))); }
public static Func <Dictionary <string, object>, object> GenerateMethod(Type type) { var da = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName("dyn"), // call it whatever you want AssemblyBuilderAccess.RunAndSave); var dm = da.DefineDynamicModule("dyn_mod", "dyn.dll"); var dt = dm.DefineType("dyn_type"); var emiter = Emit <Func <int> > .NewDynamicMethod("MyMethod"); var method = dt.DefineMethod( "Foo", MethodAttributes.Public | MethodAttributes.Static, typeof(object), new[] { typeof(Dictionary <string, object>) }); method.DefineParameter(1, ParameterAttributes.None, "dictionary"); using (var il = new GroboIL(method)) { var target = il.DeclareLocal(type); var value = il.DeclareLocal(typeof(object)); il.Newobj(type.GetConstructor(Type.EmptyTypes)); // [Person] il.Stloc(target); // [] foreach (var property in type.GetProperties()) { var label = il.DefineLabel("ifLabel"); il.Ldarg(0); // [Dictionary<String, Object>] il.Ldstr(property.Name); // [Dictionary<String, Object>, String] il.Ldloca(value); // [Dictionary<String, Object>, String, Object&] il.Call(typeof(Dictionary <string, object>) .GetMethod("TryGetValue")); // [Boolean] il.Brfalse(label); // [] il.Ldloc(target); // [Person] il.Ldloc(value); // [Person, Object] il.Castclass(typeof(string)); // [Dictionary<String, Object>, String] il.Call(property.GetSetMethod(true)); // [] il.MarkLabel(label); } il.Ldloc(target); il.Ret(); Console.WriteLine(il.GetILCode()); } dt.CreateType(); da.Save("dyn.dll"); return((dic) => dt.GetMethod("Foo").Invoke(null, new object[] { dic })); }
public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, GroboIL.Local typeSize) { il.Ldloc(offset); il.Ldloc(typeSize); il.Add(); il.Stloc(offset); }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var r = il.DeclareLocal(typeof(sbyte)); il.Ldloc(buffer); il.Ldloc(offset); il.Ldelem(typeof(byte)); if (listValue) { il.Stloc(result); } else { il.Stloc(r); } BinaryStruct.WriteOffsetAppend(il, offset, 1); if (!listValue) { il.Ldloc(result); il.Ldloc(r); il.Call(prop.Setter, isVirtual: true); } }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var r = il.DeclareLocal(typeof(TimeSpan)); var v = il.DeclareLocal(typeof(double)); il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); il.Stloc(v); il.Ldloc(v); il.Call(timeSpanConstructor); if (listValue) { il.Stloc(result); } else { il.Stloc(r); } BinaryStruct.WriteOffsetAppend(il, offset, 8); if (!listValue) { il.Ldloc(result); il.Ldloc(r); il.Call(prop.Setter, isVirtual: true); } }
public static void ReadObjectNull(GroboIL il, GroboIL.Label finishMethod, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldelem(typeof(byte)); WriteOffsetAppend(il, offset, 1); il.Brtrue(finishMethod); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 8); var arr = il.DeclareLocal(typeof(byte[])); var v = il.DeclareLocal(typeof(DateTime)); var t = il.DeclareLocal(typeof(TimeSpan)); if (!listValue) { il.Ldloc(value); var v1 = il.DeclareLocal(typeof(DateTime)); il.Call(prop.Getter); il.Stloc(v1); il.Ldloca(v1); } else { il.Ldloca(value); } il.Ldloca(v); il.Ldc_I4(1970); il.Ldc_I4(1); il.Ldc_I4(1); il.Ldc_I4(0); il.Ldc_I4(0); il.Ldc_I4(0); il.Ldc_I4(0); il.Call(datetimeConstructor); il.Ldloc(v); il.Call(substractMethod); il.Stloc(t); il.Ldloca(t); il.Call(propertyGetter); il.Call(writeBitConverterMethodInfo); il.Stloc(arr); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(arr); il.Ldc_I4(0); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); for (int i = 1; i < 8; i++) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(i); il.Add(); il.Ldloc(arr); il.Ldc_I4(i); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); } BinaryStruct.WriteOffsetAppend(il, offset, 8); }
protected override bool EmitInternal(NewExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType) { context.EmitLoadArguments(node.Arguments.ToArray()); // note ich: баг решарпера // ReSharper disable ConditionIsAlwaysTrueOrFalse // ReSharper disable HeuristicUnreachableCode GroboIL il = context.Il; if (node.Constructor != null) { il.Newobj(node.Constructor); } else { if (node.Type.IsValueType) { using (var temp = context.DeclareLocal(node.Type)) { il.Ldloca(temp); il.Initobj(node.Type); il.Ldloc(temp); } } else { throw new InvalidOperationException("Missing constructor for type '" + node.Type + "'"); } } resultType = node.Type; // ReSharper restore ConditionIsAlwaysTrueOrFalse // ReSharper restore HeuristicUnreachableCode return(false); }
private static KeyValuePair <Delegate, IntPtr> GetReader(ReaderMethodBuilderContext context, Type type) { var method = new DynamicMethod("Read_" + type.Name + "_AndCastToObject_" + Guid.NewGuid(), typeof(void), new[] { typeof(IntPtr), typeof(int).MakeByRefType(), typeof(object).MakeByRefType(), typeof(ReaderContext) }, context.Context.Module, true); using (var il = new GroboIL(method)) { il.Ldarg(2); // stack: [ref result] il.Ldarg(0); // stack: [ref result, data] il.Ldarg(1); // stack: [ref result, data, ref index] var value = il.DeclareLocal(type); il.Ldloca(value); // stack: [ref result, data, ref index, ref value] il.Ldarg(3); // stack: [ref result, data, ref index, ref value, context] ReaderMethodBuilderContext.CallReader(il, type, context.Context); il.Ldloc(value); // stack: [ref result, value] if (type.IsValueType) { il.Box(type); // stack: [ref result, (object)value] } else { il.Castclass(type); } il.Stind(typeof(object)); // result = (object)value il.Ret(); } var @delegate = method.CreateDelegate(typeof(ReaderDelegate)); return(new KeyValuePair <Delegate, IntPtr>(@delegate, GroBufHelpers.ExtractDynamicMethodPointer(method))); }
public static void WriteOffsetAppend(GroboIL il, GroboIL.Local offset, int len) { il.Ldloc(offset); il.Ldc_I4(len); il.Add(); il.Stloc(offset); }
protected override bool EmitInternal(MemberInitExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType) { ExpressionEmittersCollection.Emit(node.NewExpression, context, out resultType); // stack: [new obj(args)] GroboIL il = context.Il; if (!node.Type.IsValueType) { foreach (MemberAssignment assignment in node.Bindings) { il.Dup(); context.EmitLoadArguments(assignment.Expression); context.EmitMemberAssign(node.Type, assignment.Member); } } else { using (var temp = context.DeclareLocal(node.Type)) { il.Stloc(temp); il.Ldloca(temp); foreach (MemberAssignment assignment in node.Bindings) { il.Dup(); context.EmitLoadArguments(assignment.Expression); context.EmitMemberAssign(node.Type, assignment.Member); } // todo или il.Ldobj()? il.Pop(); il.Ldloc(temp); } } return(false); }
public void WithExceptions() { var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(string), true); using (var il = new GroboIL(dynamicMethod, false)) { var endLabel = il.DefineLabel("end"); var resultLocal = il.DeclareLocal(typeof(int), "result"); il.BeginExceptionBlock(); il.Ldarg(0); il.Ldarg(1); il.Div(false); il.Stloc(resultLocal); il.BeginCatchBlock(typeof(DivideByZeroException)); il.Pop(); il.WriteLine("Division by zero caught"); il.Ldc_I4(0); il.Stloc(resultLocal); il.BeginFinallyBlock(); il.WriteLine("It is finally"); il.EndExceptionBlock(); il.MarkLabel(endLabel); il.Ldloc(resultLocal); il.Ret(); } DynamicMethodTracingInstaller.InstallTracing(dynamicMethod); var func = (Func <int, int, int>)dynamicMethod.CreateDelegate(typeof(Func <int, int, int>)); Console.WriteLine(func(12, 5)); Console.WriteLine(func(5, 0)); }
private static TryParseDelegate EmitTryParseDelegate() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(string), typeof(DateTimeTypeCode), typeof(object).MakeByRefType() }, typeof(string), true); var xsdDateTimeType = typeof(XmlReader).Assembly.GetTypes().FirstOrDefault(type => type.Name == "XsdDateTime"); if (xsdDateTimeType == null) { throw new InvalidOperationException("The type 'XsdDateTime' is not found"); } var tryParseMethod = xsdDateTimeType.GetMethod("TryParse", BindingFlags.Static | BindingFlags.NonPublic); if (tryParseMethod == null) { throw new InvalidOperationException("The method 'XsdDateTime.TryParse' is not found"); } using (var il = new GroboIL(method)) { il.Ldarg(0); // stack: [value] il.Ldarg(1); // stack: [value, typeCode] var strongBoxType = typeof(StrongBox <>).MakeGenericType(xsdDateTimeType); var strongBox = il.DeclareLocal(strongBoxType); il.Ldarg(2); // stack: [value, typeCode, ref result] il.Newobj(strongBoxType.GetConstructor(Type.EmptyTypes)); // stack: [value, typeCode, ref result, new StrongBox<XsdDateTime>()] il.Dup(); il.Stloc(strongBox); // strongBox = new StrongBox<XsdDateTime>(); stack: [value, typeCode, ref result, strongBox] il.Stind(typeof(object)); // result = strongBox; stack: [value, typeCode] il.Ldloc(strongBox); // stack: [value, typeCode, strongBox] il.Ldflda(strongBoxType.GetField("Value", BindingFlags.Instance | BindingFlags.Public)); // stack: [value, typeCode, ref strongBox.Value] il.Call(tryParseMethod); // stack: [XsdDateTime.TryParse(value, typeCode, ref strongBox.Value] il.Ret(); } return((TryParseDelegate)method.CreateDelegate(typeof(TryParseDelegate))); }
private static void EmitMinusMinusX(this GroboIL il, GroboIL.Local intLocal) { il.Ldloc(intLocal); il.Ldc_I4(1); il.Sub(); il.Dup(); il.Stloc(intLocal); }
private static void EmitXPlusPlus(this GroboIL il, GroboIL.Local intLocal) { il.Ldloc(intLocal); il.Dup(); il.Ldc_I4(1); il.Add(); il.Stloc(intLocal); }
private void CompileReader() { DynamicMethod dm = new DynamicMethod(Guid.NewGuid().ToString(), typeof(Tuple <int, object>), new[] { typeof(byte[]), typeof(BinaryStruct), typeof(int) }); using (var il = new GroboIL(dm)) { var offset = il.DeclareLocal(typeof(int)); var result = il.DeclareLocal(this.Type); var typeSize = il.DeclareLocal(typeof(int)); var buffer = il.DeclareLocal(typeof(byte[])); var binaryStruct = il.DeclareLocal(typeof(BinaryStruct)); il.Ldarg(1); il.Stloc(binaryStruct); var constr = GetConstructor(result.Type, null); if (constr == null) { throw new Exception($"Type {result.Type} not have constructor with not parameters"); } il.Ldarg(0); il.Stloc(buffer); il.Ldarg(2); il.Stloc(offset); il.Newobj(constr); il.Stloc(result); CompileReader(this, il, binaryStruct, buffer, offset, result, typeSize); il.Ldloc(offset); il.Ldloc(result); il.Newobj(typeof(Tuple <int, object>).GetConstructor(new Type[] { typeof(int), typeof(object) })); il.Ret(); IlReadCode = il.GetILCode(); } //ReadMethod = (ReadMethodDelegate)dm.CreateDelegate(typeof(ReadMethodDelegate)); ReadMethod = CreateReader(dm); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 1); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(value); if (!listValue) { il.Call(prop.Getter); } il.Stelem(typeof(byte)); BinaryStruct.WriteOffsetAppend(il, offset, 1); }
public void GetWriteILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local typeSize, GroboIL.Local buffer, GroboIL.Local offset, bool listValue) { BinaryStruct.WriteSizeChecker(il, buffer, offset, 2); var arr = il.DeclareLocal(typeof(byte[])); il.Ldloc(value); if (!listValue) { il.Call(prop.Getter); } il.Dup(); il.Pop(); il.Call(writeBitConverterMethodInfo); il.Stloc(arr); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(arr); il.Ldc_I4(0); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); for (int i = 1; i < 2; i++) { il.Ldloc(buffer); il.Ldloc(offset); il.Ldc_I4(i); il.Add(); il.Ldloc(arr); il.Ldc_I4(i); il.Ldelem(typeof(byte)); il.Stelem(typeof(byte)); } BinaryStruct.WriteOffsetAppend(il, offset, 2); }
public static void WriteSizeChecker(GroboIL il, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { //il.Ldloca(buffer); //il.Ldloc(offset); //il.Ldloc(typeSize); //il.Call(resizeMethod); il.Ldloc(typeSize); Resize(il, buffer, offset); }
public void GetReadILCode(PropertyData prop, BinaryStruct currentStruct, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local result, GroboIL.Local typeSize, GroboIL.Local offset, bool listValue) { var exitLabel = il.DefineLabel("exit"); BinaryStruct.ReadObjectNull(il, exitLabel, buffer, offset, typeSize); var val = il.DeclareLocal(typeof(TType)); (new T()).GetReadILCode(prop, currentStruct, il, binaryStruct, buffer, val, typeSize, offset, true); il.Ldloc(result); il.Ldloc(val); il.Newobj(Setter); il.Call(prop.Setter); il.MarkLabel(exitLabel); }
public void TestDifferentStructs() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(int) }, typeof(Test)); var il = new GroboIL(method); var loc1 = il.DeclareLocal(typeof(int?)); var loc2 = il.DeclareLocal(typeof(Qxx?)); var label1 = il.DefineLabel("zzz"); il.Ldarg(0); il.Brfalse(label1); il.Ldloc(loc1); var label2 = il.DefineLabel("qxx"); il.Br(label2); il.MarkLabel(label1); il.Ldloc(loc2); Assert.Throws <InvalidOperationException>(() => il.MarkLabel(label2)); }
private Func <string, string> BuildSwitch4() { Init(new[] { "0", "2", "5", "1000001", "7", "1000000" }); var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(string), new[] { typeof(string) }, Module, true); using (var il = new GroboIL(dynamicMethod)) { var zzzLabel = il.DefineLabel("zzz"); var qxxLabel = il.DefineLabel("qxx"); var qzzLabel = il.DefineLabel("qzz"); var xxxLabel = il.DefineLabel("xxx"); var index = il.DeclareLocal(typeof(uint)); il.Ldfld(typeof(TestPerformance).GetField("testValues2")); il.Ldarg(0); il.Call(typeof(object).GetMethod("GetHashCode"), typeof(string)); il.Ldc_I4(testValues2.Length); il.Rem(true); il.Stloc(index); il.Ldloc(index); il.Ldelem(typeof(string)); il.Ldarg(0); il.Call(typeof(object).GetMethod("Equals", new[] { typeof(object) }), typeof(string)); il.Brfalse(xxxLabel); il.Ldfld(typeof(TestPerformance).GetField("indexes2")); il.Ldloc(index); il.Ldelem(typeof(int)); il.Switch(zzzLabel, zzzLabel, qxxLabel, qxxLabel, qzzLabel, qzzLabel); il.Br(xxxLabel); il.MarkLabel(zzzLabel); il.Ldstr("zzz"); il.Ret(); il.MarkLabel(qxxLabel); il.Ldstr("qxx"); il.Ret(); il.MarkLabel(qzzLabel); il.Ldstr("qzz"); il.Ret(); il.MarkLabel(xxxLabel); il.Ldstr("xxx"); il.Ret(); } return((Func <string, string>)dynamicMethod.CreateDelegate(typeof(Func <string, string>))); }
public static void WriteObjectNull(GroboIL il, GroboIL.Label finishMethod, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { var _null = il.DeclareLocal(typeof(bool)); il.Ldnull(); il.Ceq(); il.Stloc(_null); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(_null); il.Stelem(typeof(byte)); WriteOffsetAppend(il, offset, 1); il.Ldloc(_null); il.Brtrue(finishMethod); }
public void BuildSizeCounter(SizeCounterBuilderContext sizeCounterBuilderContext) { var method = new DynamicMethod("Count_" + Type.Name + "_" + Guid.NewGuid(), typeof(int), new[] { Type, typeof(bool), typeof(WriterContext) }, sizeCounterBuilderContext.Module, true); sizeCounterBuilderContext.SetSizeCounterMethod(Type, method); using (var il = new GroboIL(method)) { var context = new SizeCounterMethodBuilderContext(sizeCounterBuilderContext, il); var notEmptyLabel = il.DefineLabel("notEmpty"); if (CheckEmpty(context, notEmptyLabel)) // Check if obj is empty { context.ReturnForNull(); // return for null } il.MarkLabel(notEmptyLabel); // Now we know that obj is not empty if (!Type.IsValueType && IsReference && sizeCounterBuilderContext.GroBufWriter.Options.HasFlag(GroBufOptions.PackReferences)) { // Pack reference var index = il.DeclareLocal(typeof(int)); context.LoadContext(); // stack: [context] il.Dup(); // stack: [context, context] il.Ldfld(WriterContext.IndexField); // stack: [context, context.index] il.Stloc(index); // index = context.index; stack: [context] il.Ldfld(WriterContext.ObjectsField); // stack: [context.objects] context.LoadObj(); // stack: [context.objects, obj] il.Call(HackHelpers.GetMethodDefinition <Dictionary <object, int> >(dict => dict.ContainsKey(null))); // stack: [context.object.ContainsKey(obj)] var storeLocationLabel = il.DefineLabel("storeLocation"); il.Brfalse(storeLocationLabel); // if(!context.objects.ContainsKey(obj)) goto storeLocation; stack: [] context.LoadContext(); // stack: [context] il.Dup(); // stack: [context, context] il.Ldfld(WriterContext.ReferencesField); // stack: [context, context.references] il.Ldc_I4(1); // stack: [context, context.references, 1] il.Add(); // stack: [context, context.references + 1] il.Stfld(WriterContext.ReferencesField); // context.references += 1; stack: [] il.Ldc_I4(5); // stack: [5] il.Ret(); // return 5 il.MarkLabel(storeLocationLabel); context.LoadContext(); // stack: [context] il.Ldfld(typeof(WriterContext).GetField("objects", BindingFlags.Public | BindingFlags.Instance)); // stack: [context.objects] context.LoadObj(); // stack: [context.objects, obj] il.Ldloc(index); // stack: [context.objects, obj, index] il.Call(HackHelpers.GetMethodDefinition <Dictionary <object, int> >(dict => dict.Add(null, 0))); // context.objects.Add(obj, index); } CountSizeNotEmpty(context); // Count size il.Ret(); } var @delegate = method.CreateDelegate(typeof(SizeCounterDelegate <>).MakeGenericType(Type)); var pointer = GroBufHelpers.ExtractDynamicMethodPointer(method); sizeCounterBuilderContext.SetSizeCounterPointer(Type, pointer, @delegate); }
public void TestFarsh() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int) }, typeof(Test)); using (var il = new GroboIL(method)) { var temp = il.DeclareLocal(typeof(int)); il.Ldarg(0); // stack: [x] var label0 = il.DefineLabel("L"); il.Br(label0); // goto L_0; stack: [x] il.Ldstr("zzz"); il.Ldobj(typeof(DateTime)); il.Mul(); il.Initobj(typeof(int)); var label1 = il.DefineLabel("L"); il.MarkLabel(label1); // stack: [x, 2] il.Stloc(temp); // temp = 2; stack: [x] var label2 = il.DefineLabel("L"); il.MarkLabel(label2); // stack: [cur] il.Ldarg(0); // stack: [cur, x] il.Mul(); // stack: [cur * x = cur] il.Ldloc(temp); // stack: [cur, temp] il.Ldc_I4(1); // stack: [cur, temp, 1] il.Sub(); // stack: [cur, temp - 1] il.Stloc(temp); // temp = temp - 1; stack: [cur] il.Ldloc(temp); // stack: [cur, temp] il.Ldc_I4(0); // stack: [cur, temp, 0] il.Bgt(label2, false); // if(temp > 0) goto L_2; stack: [cur] var label3 = il.DefineLabel("L"); il.Br(label3); // goto L_3; stack: [cur] il.MarkLabel(label0); // stack: [x] il.Ldc_I4(2); // stack: [x, 2] il.Br(label1); // goto L_1; stack: [x, 2] il.MarkLabel(label3); // stack: [cur] il.Ret(); // return cur; stack: [] Console.Write(il.GetILCode()); } }
private Func <int, string> BuildSwitch2() { var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(string), new[] { typeof(int) }, Module, true); using (var il = new GroboIL(dynamicMethod)) { var zzzLabel = il.DefineLabel("zzz"); var qxxLabel = il.DefineLabel("qxx"); var qzzLabel = il.DefineLabel("qzz"); var xxxLabel = il.DefineLabel("xxx"); var index = il.DeclareLocal(typeof(uint)); il.Ldfld(typeof(TestPerformance).GetField("testValues")); il.Ldarg(0); il.Ldc_I4(14); il.Rem(true); il.Stloc(index); il.Ldloc(index); il.Ldelem(typeof(int)); il.Ldarg(0); il.Bne_Un(xxxLabel); il.Ldfld(typeof(TestPerformance).GetField("indexes")); il.Ldloc(index); il.Ldelem(typeof(int)); il.Switch(zzzLabel, zzzLabel, qxxLabel, qzzLabel, qzzLabel, qxxLabel); il.Br(xxxLabel); il.MarkLabel(zzzLabel); il.Ldstr("zzz"); il.Ret(); il.MarkLabel(qxxLabel); il.Ldstr("qxx"); il.Ret(); il.MarkLabel(qzzLabel); il.Ldstr("qzz"); il.Ret(); il.MarkLabel(xxxLabel); il.Ldstr("xxx"); il.Ret(); } return((Func <int, string>)dynamicMethod.CreateDelegate(typeof(Func <int, string>))); }
public static void CompileReader(BinaryStruct bs, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local result, GroboIL.Local typeSize) { if (bs.PropertyList.Count > 0) { foreach (var item in bs.PropertyList) { if (item.IsBaseType) { item.BinaryType.GetReadILCode(item, bs, il, binaryStruct, buffer, result, typeSize, offset, false); continue; } var methodBreak = il.DefineLabel("breakReadMethod"); ReadObjectNull(il, methodBreak, buffer, offset, typeSize); var in_value = il.DeclareLocal(item.PropertyInfo.PropertyType); var constr = BinaryStruct.GetConstructor(item.PropertyInfo.PropertyType, null); if (constr == null) { throw new Exception($"Type {item.PropertyInfo.PropertyType} not have constructor with not parameters"); } il.Newobj(constr); il.Stloc(in_value); CompileReader(item.BinaryStruct, il, binaryStruct, buffer, offset, in_value, typeSize); il.Ldloc(result); il.Ldloc(in_value); il.Call(item.Setter, isVirtual: true); il.MarkLabel(methodBreak); //il.Pop(); } } }
private void CompileWriter() { DynamicMethod dm = new DynamicMethod(Guid.NewGuid().ToString(), typeof(Tuple <int, byte[]>), new[] { Type, typeof(BinaryStruct) }); using (var il = new GroboIL(dm)) { var buffer = il.DeclareLocal(typeof(byte[])); var offset = il.DeclareLocal(typeof(int)); var typeSize = il.DeclareLocal(typeof(int)); var value = il.DeclareLocal(Type); var binaryStruct = il.DeclareLocal(typeof(BinaryStruct)); il.Ldarg(1); il.Stloc(binaryStruct); il.Ldarg(0); //il.Castclass(Type); il.Stloc(value); il.Ldc_I4(InitLen); il.Newarr(typeof(byte)); il.Stloc(buffer); CompileWriter(this, il, binaryStruct, value, buffer, offset, typeSize); il.Ldloc(offset); il.Ldloc(buffer); il.Newobj(typeof(Tuple <int, byte[]>).GetConstructor(new Type[] { typeof(int), typeof(byte[]) })); il.Ret(); IlWriteCode = il.GetILCode(); } WriteMethod = CreateWriter(dm); }
private static void EmitDefaultTypeValue(GroboIL il, Type type) { switch (Type.GetTypeCode(type)) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Boolean: case TypeCode.Char: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: il.Ldc_I4(0); return; case TypeCode.Int64: case TypeCode.UInt64: il.Ldc_I8(0); return; case TypeCode.Single: il.Ldc_R4(0f); return; case TypeCode.Double: il.Ldc_R8(0d); return; } if (type.IsPointer || type == typeof(UIntPtr) || type == typeof(IntPtr)) { il.Ldc_IntPtr(IntPtr.Zero); il.Conv <UIntPtr>(); } else if (type.IsEnum) { EmitDefaultTypeValue(il, Enum.GetUnderlyingType(type)); } else if (type.IsValueType) { var local = il.DeclareLocal(type); il.Ldloca(local); il.Initobj(type); il.Ldloc(local); } else { il.Ldnull(); } }