public void TestDifferentPathsGeneric() { var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); var module = assembly.DefineDynamicModule(Guid.NewGuid().ToString()); var type = module.DefineType("Zzz", TypeAttributes.Class | TypeAttributes.Public); var method = type.DefineMethod("Qzz", MethodAttributes.Public | MethodAttributes.Static); var genericParameters = method.DefineGenericParameters("TZzz"); var parameter = genericParameters[0]; method.SetParameters(typeof(bool), typeof(C1 <>).MakeGenericType(parameter), typeof(C2 <>).MakeGenericType(parameter)); method.SetReturnType(typeof(void)); using (var il = new GroboIL(method)) { il.Ldarg(0); var label1 = il.DefineLabel("L1"); il.Brfalse(label1); il.Ldarg(1); var label2 = il.DefineLabel("L2"); il.Br(label2); il.MarkLabel(label1); il.Ldarg(2); il.MarkLabel(label2); il.Dup(); il.Call(HackHelpers.GetMethodDefinition <I1 <int> >(x => F1(x)).GetGenericMethodDefinition().MakeGenericMethod(parameter)); il.Call(HackHelpers.GetMethodDefinition <I2 <int> >(x => F2(x)).GetGenericMethodDefinition().MakeGenericMethod(parameter)); il.Ret(); Console.Write(il.GetILCode()); } }
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 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 Func <MethodBase, DynamicMethod> EmitTryCastToDynamicMethod() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(DynamicMethod), new[] { typeof(MethodBase) }, typeof(string), true); using (var il = new GroboIL(method)) { var RTDynamicMethod_t = typeof(DynamicMethod).GetNestedType("RTDynamicMethod", BindingFlags.NonPublic); if (RTDynamicMethod_t == null) { throw new InvalidOperationException("Missing type 'System.Reflection.Emit.DynamicMethod.RTDynamicMethod'"); } il.Ldarg(0); // stack: [method] il.Isinst(RTDynamicMethod_t); // stack: [method as RTDynamicMethod] il.Dup(); // stack: [method as RTDynamicMethod, method as RTDynamicMethod] var retLabel = il.DefineLabel("ret"); il.Brfalse(retLabel); // if(!(method is RTDynamicMethod)] goto ret; stack: [method as RTDynamicMethod] var m_owner_f = RTDynamicMethod_t.GetField("m_owner", BindingFlags.Instance | BindingFlags.NonPublic); if (m_owner_f == null) { throw new InvalidOperationException("Missing field 'System.Reflection.Emit.DynamicMethod.RTDynamicMethod.m_owner'"); } il.Ldfld(m_owner_f); // stack: [((RTDynamicMethod)method).m_owner] il.MarkLabel(retLabel); il.Ret(); } return((Func <MethodBase, DynamicMethod>)method.CreateDelegate(typeof(Func <MethodBase, DynamicMethod>))); }
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 })); }
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 void TestLabelHasBeenMarkedTwice() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), Type.EmptyTypes, typeof(string), true); var il = new GroboIL(method); var label = il.DefineLabel("L"); il.Ldc_I4(0); il.Brfalse(label); il.Ldc_I4(1); il.Pop(); il.MarkLabel(label); il.Ldc_I4(2); il.Pop(); var e = Assert.Throws <InvalidOperationException>(() => il.MarkLabel(label)); Assert.AreEqual("The label 'L_0' has already been marked", e.Message); }
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)); }
public static Delegate Emit(Type type) { Console.WriteLine("EMITTING " + type); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { type, type }, type, true); using (var il = new GroboIL(method)) { var r0 = il.DefineLabel("Return_0", false); // todo: inheritance // todo: public/private // todo: fields // todo: options for public/private, field/property var props = type.GetProperties(); foreach (var propertyInfo in props) { // todo: nullable // todo: array // todo: struct (DateTime, Guid) var propertyType = propertyInfo.PropertyType; var nullableType = Nullable.GetUnderlyingType(propertyType); if (BneTypes.Contains(propertyType) || propertyType.IsEnum) { EmitBne(il, propertyInfo.GetMethod, r0); } else if (StaticEqualsTypes.ContainsKey(propertyType)) { EmitStatic(il, propertyInfo.GetMethod, StaticEqualsTypes[propertyType], r0); } else if (InstanceEqualsTypes.ContainsKey(propertyType)) { EmitInstance(il, propertyInfo.GetMethod, InstanceEqualsTypes[propertyType], r0); } else if (nullableType != null && (BneTypes.Contains(nullableType) || nullableType.IsEnum)) { EmitNullableBne(il, propertyInfo.GetMethod, r0); } else if (nullableType != null) { EmitNullableEquals(il, propertyInfo.GetMethod, r0); } else { EmitStatic(il, propertyInfo.GetMethod, EmittedEquals, r0); } } il.Ldc_I4(1); il.Ret(); il.MarkLabel(r0); il.Ldc_I4(0); il.Ret(); Console.WriteLine(il.GetILCode()); } return(method.CreateDelegate(typeof(Func <, ,>).MakeGenericType(type, type, typeof(bool)))); }
public void TestZ2() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(A), new[] { typeof(bool), typeof(B), typeof(C) }, typeof(Test)); using (var il = new GroboIL(method)) { il.Ldarg(0); var label1 = il.DefineLabel("label"); il.Brfalse(label1); il.Ldarg(1); var label2 = il.DefineLabel("label"); il.Br(label2); il.MarkLabel(label1); il.Ldarg(2); il.MarkLabel(label2); il.Ret(); Console.Write(il.GetILCode()); } }
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 TryGetValueDelegate <T> Build <T>(string[] keys, T[] values, Func <string, int> hashCodeEvaluator) { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(Closure <T>), typeof(string), typeof(T).MakeByRefType() }, typeof(string), true); var hashCodes = keys.Select(hashCodeEvaluator).ToArray(); int n = keys.Length; var indexes = new int[n]; for (int i = 0; i < n; ++i) { indexes[i] = i; } Array.Sort(indexes, (lhs, rhs) => hashCodes[lhs].CompareTo(hashCodes[rhs])); using (var il = new GroboIL(method)) { var retFalseLabel = il.DefineLabel("retFalse"); var hashCode = il.DeclareLocal(typeof(int), "hashCode"); il.Ldarg(0); // stack: [closure] il.Ldfld(HackHelpers.GetField <Closure <T> >(x => x.hashCodeEvaluator)); // stack: [closure.hashCodeEvaluator] il.Ldarg(1); // stack: [closure.hashCodeEvaluator, key] il.Call(typeof(Func <string, int>).GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)); // stack: [closure.hashCodeEvaluator(key)] il.Stloc(hashCode); // hashCode = closure.hashCodeEvaluator(key); stack: [] var context = new EmittingContext { Il = il, Keys = keys, HashCodes = hashCodes, Indexes = indexes, HashCode = hashCode, RetFalseLabel = retFalseLabel }; DoBinarySearch <T>(context, 0, n - 1); il.MarkLabel(retFalseLabel); il.Ldarg(2); // stack: [ref value] if (typeof(T).IsValueType) { il.Initobj(typeof(T)); // value = default(T); stack: [] } else { il.Ldnull(); // stack: [ref value, null] il.Stind(typeof(T)); // value = null; stack: [] } il.Ldc_I4(0); // stack: [false] il.Ret(); } var closure = new Closure <T> { hashCodeEvaluator = hashCodeEvaluator, values = values }; return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), closure)); }
public void TestBrtrue() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(C2) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Dup(); var label = il.DefineLabel("L"); il.Brtrue(label); var label2 = il.DefineLabel("L"); il.Br(label2); il.MarkLabel(label); il.Call(HackHelpers.GetMethodDefinition <I1>(x => x.GetI2())); il.MarkLabel(label2); il.Call(HackHelpers.GetMethodDefinition <int>(x => F2(null))); il.Ret(); Console.WriteLine(il.GetILCode()); } }
private IQxx BuildIfs(ModuleBuilder module, string[] keys) { var numberOfCases = keys.Length; var typeBuilder = module.DefineType("Ifs" + Guid.NewGuid(), TypeAttributes.Class | TypeAttributes.Public); typeBuilder.AddInterfaceImplementation(typeof(IQxx)); var fields = new FieldInfo[numberOfCases]; for (var i = 0; i < numberOfCases; ++i) { fields[i] = typeBuilder.DefineField(keys[i], typeof(int), FieldAttributes.Public); } var method = typeBuilder.DefineMethod("Set", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), new[] { typeof(string), typeof(int) }); method.DefineParameter(1, ParameterAttributes.In, "key"); method.DefineParameter(2, ParameterAttributes.In, "value"); using (var il = new GroboIL(method)) { var doneLabel = il.DefineLabel("done"); for (var i = 0; i < numberOfCases; ++i) { il.Ldarg(1); // stack: [key] il.Ldstr(keys[i]); // stack: [key, keys[i]] il.Call(stringEqualityOperator); // stack: [key == keys[i]] var nextKeyLabel = il.DefineLabel("nextKey"); il.Brfalse(nextKeyLabel); // if(key != keys[i]) goto nextKey; stack: [] il.Ldarg(0); il.Ldarg(2); il.Stfld(fields[i]); il.Br(doneLabel); il.MarkLabel(nextKeyLabel); } il.MarkLabel(doneLabel); il.Ret(); } typeBuilder.DefineMethodOverride(method, typeof(IQxx).GetMethod("Set")); var type = typeBuilder.CreateType(); return((IQxx)Activator.CreateInstance(type)); }
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>))); }
private static void EmitCrashIfValueIsNull(GroboIL il) { var box = il.DefineLabel("box"); il.Dup(); il.Brtrue(box); var crashConstructor = typeof(ArgumentException).GetConstructor(new[] { typeof(string) }); il.Ldstr("bad parameter"); il.Newobj(crashConstructor); il.Throw(); il.MarkLabel(box); }
public void TestDifferentPaths() { Console.WriteLine(Formatter.Format(typeof(Dictionary <string, int>).GetProperty("Values", BindingFlags.Public | BindingFlags.Instance).GetGetMethod())); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(bool), typeof(C1), typeof(C2) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); var label1 = il.DefineLabel("L1"); il.Brfalse(label1); il.Ldarg(1); var label2 = il.DefineLabel("L2"); il.Br(label2); il.MarkLabel(label1); il.Ldarg(2); il.MarkLabel(label2); il.Dup(); il.Call(HackHelpers.GetMethodDefinition <I1>(x => F1(x))); il.Call(HackHelpers.GetMethodDefinition <I2>(x => F2(x))); il.Ret(); Console.Write(il.GetILCode()); } var action = method.CreateDelegate(typeof(Action <bool, C1, C2>)); }
private Func <int, string> BuildSwitch1() { 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)) { il.Ldarg(0); var zzzLabel = il.DefineLabel("zzz"); var qxxLabel = il.DefineLabel("qxx"); var qzzLabel = il.DefineLabel("qzz"); var xxxLabel = il.DefineLabel("xxx"); il.Switch(zzzLabel, xxxLabel, zzzLabel); il.Ldarg(0); il.Ldc_I4(5); il.Sub(); il.Switch(qxxLabel, xxxLabel, qzzLabel); il.Ldarg(0); il.Ldc_I4(0xf4240); il.Sub(); il.Switch(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 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 len = il.DeclareLocal(typeof(int)); il.Ldloc(buffer); il.Ldloc(offset); il.Call(readBitConverterMethodInfo); il.Stloc(len); BinaryStruct.WriteOffsetAppend(il, offset, 4); if (!listValue) { il.Ldloc(result); il.Ldarg(1); } else { il.Ldloc(binaryStruct); } il.Call(codingMethodInfo); il.Castclass(typeof(UTF8Encoding)); il.Ldloc(buffer); il.Ldloc(offset); il.Ldloc(len); il.Call(currentStruct.Coding.GetType().GetMethod("GetString", new Type[] { typeof(byte[]), typeof(int), typeof(int) }), isVirtual: true); if (!listValue) { il.Call(prop.Setter); } else { il.Stloc(result); } BinaryStruct.WriteOffsetAppend(il, offset, len); il.MarkLabel(exitLabel); }
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 TestMax() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int) }, typeof(Test)); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Ldarg(1); var returnSecondLabel = il.DefineLabel("returnSecond"); il.Ble(returnSecondLabel, false); il.Ldarg(0); il.Ret(); il.MarkLabel(returnSecondLabel); il.Ldarg(1); il.Ret(); Console.Write(il.GetILCode()); } }
public static Delegate Emit(Type type) { Console.WriteLine("EMITTING " + type); var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof (bool), new[] { type, type }, type, true); using (var il = new GroboIL(method)) { var r0 = il.DefineLabel("Return_0", false); // todo: inheritance // todo: public/private // todo: fields // todo: options for public/private, field/property var props = type.GetProperties(); foreach (var propertyInfo in props) { // todo: nullable // todo: array // todo: struct (DateTime, Guid) var propertyType = propertyInfo.PropertyType; var nullableType = Nullable.GetUnderlyingType(propertyType); if (BneTypes.Contains(propertyType) || propertyType.IsEnum) EmitBne(il, propertyInfo.GetMethod, r0); else if (StaticEqualsTypes.ContainsKey(propertyType)) EmitStatic(il, propertyInfo.GetMethod, StaticEqualsTypes[propertyType], r0); else if (InstanceEqualsTypes.ContainsKey(propertyType)) EmitInstance(il, propertyInfo.GetMethod, InstanceEqualsTypes[propertyType], r0); else if (nullableType != null && (BneTypes.Contains(nullableType) || nullableType.IsEnum)) EmitNullableBne(il, propertyInfo.GetMethod, r0); else if (nullableType != null) EmitNullableEquals(il, propertyInfo.GetMethod, r0); else EmitStatic(il, propertyInfo.GetMethod, EmittedEquals, r0); } il.Ldc_I4(1); il.Ret(); il.MarkLabel(r0); il.Ldc_I4(0); il.Ret(); Console.WriteLine(il.GetILCode()); } return method.CreateDelegate(typeof(Func<,,>).MakeGenericType(type, type, typeof(bool))); }
public static void ProcessWrite(PropertyData item, BinaryStruct bs, GroboIL il, GroboIL.Local binaryStruct, GroboIL.Local value, GroboIL.Local buffer, GroboIL.Local offset, GroboIL.Local typeSize) { if (!string.IsNullOrEmpty(item.BinaryAttr?.ArraySizeName)) { item.ArraySizeProperty = bs.PropertyList.Find(x => x.PropertyInfo.Name == item.BinaryAttr.ArraySizeName); if (item.ArraySizeProperty == null) { throw new Exception($"ArraySizeProperty \"{item.BinaryAttr.ArraySizeName}\" for {item.PropertyInfo.Name} in Struct {bs.Type}:{item.PropertyInfo.DeclaringType} not found(Scheme: {bs.Scheme})"); } } if (!string.IsNullOrEmpty(item.BinaryAttr?.TypeSizeName)) { item.TypeSizeProperty = bs.PropertyList.Find(x => x.PropertyInfo.Name == item.BinaryAttr.TypeSizeName); if (item.TypeSizeProperty == null) { throw new Exception($"TypeSizeProperty \"{item.BinaryAttr.TypeSizeName}\" for {item.PropertyInfo.Name} in Struct {bs.Type}:{item.PropertyInfo.DeclaringType} not found(Scheme: {bs.Scheme})"); } } if (item.IsBaseType) { item.BinaryType.GetWriteILCode(item, bs, il, binaryStruct, value, typeSize, buffer, offset, false); return; } var methodBreak = il.DefineLabel("breakWriteMethod"); var in_value = il.DeclareLocal(item.PropertyInfo.PropertyType); //значение вложенного класса il.Ldloc(value); il.Call(item.PropertyInfo.GetGetMethod()); il.Stloc(in_value); WriteSizeChecker(il, buffer, offset, 2); WriteObjectNull(il, methodBreak, in_value, buffer, offset, typeSize); CompileWriter(item.BinaryStruct, il, binaryStruct, in_value, buffer, offset, typeSize); il.MarkLabel(methodBreak); //il.Pop(); }
private static void BuildJump(TypeBuilder typeBuilder, int n, Context context) { var method = typeBuilder.DefineMethod("Jump", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(MethodCallNode), new[] { typeof(int) }); using (var il = new GroboIL(method)) { var retNullLabel = il.DefineLabel("retNull"); var emittingContext = new MethodJumpEmittingContext { context = context, il = il, retNullLabel = retNullLabel }; DoBinarySearch(emittingContext, 0, n - 1); il.MarkLabel(retNullLabel); il.Ldnull(); il.Ret(); } typeBuilder.DefineMethodOverride(method, typeof(MethodCallNodeEdges).GetMethod(method.Name, BindingFlags.Public | BindingFlags.Instance)); }
public static TryGetValueDelegate <T> Build <T>(char[] keys, T[] values) { // Assuming keys are sorted var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(T[]), typeof(char), typeof(T).MakeByRefType() }, typeof(string), true); //var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("zzz"), AssemblyBuilderAccess.RunAndSave); //var module = assembly.DefineDynamicModule("qxx", "zzz.dll"); //var typeBuilder = module.DefineType("Zzz", TypeAttributes.Class | TypeAttributes.Public); //var method = typeBuilder.DefineMethod("do_switch", MethodAttributes.Public | MethodAttributes.Static, // typeof(bool), new[] {typeof(T[]), typeof(char), typeof(T).MakeByRefType()}); int n = keys.Length; using (var il = new GroboIL(method)) { var retFalseLabel = il.DefineLabel("retFalse"); var context = new EmittingContext { Il = il, Keys = keys, RetFalseLabel = retFalseLabel }; DoBinarySearch <T>(context, 0, n - 1); il.MarkLabel(retFalseLabel); il.Ldarg(2); // stack: [ref value] if (typeof(T).IsValueType) { il.Initobj(typeof(T)); // value = default(T); stack: [] } else { il.Ldnull(); // stack: [ref value, null] il.Stind(typeof(T)); // value = null; stack: [] } il.Ldc_I4(0); // stack: [false] il.Ret(); } //typeBuilder.CreateType(); //assembly.Save("zzz.dll"); //return null; return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), values)); }
private static Func <object, object> EmitResolveVarArgsMethod() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(object), new[] { typeof(object) }, typeof(string), true); using (var il = new GroboIL(method)) { var VarArgMethod_t = typeof(DynamicMethod).Assembly.GetType("System.Reflection.Emit.VarArgMethod"); if (VarArgMethod_t == null) { throw new InvalidOperationException("Missing type 'System.Reflection.Emit.VarArgMethod'"); } il.Ldarg(0); // stack: [value] il.Isinst(VarArgMethod_t); // stack: [(VarArgMethod)value] var retLabel = il.DefineLabel("ret"); il.Dup(); // stack: [(VarArgMethod)value, (VarArgMethod)value] il.Brfalse(retLabel); // if(!(value is VarArgMethod)) goto ret; stack: [value as VarArgMethod] var m_method_f = VarArgMethod_t.GetField("m_method", BindingFlags.Instance | BindingFlags.NonPublic); if (m_method_f == null) { throw new InvalidOperationException("Missing field 'System.Reflection.Emit.VarArgMethod.m_method'"); } var m_dynamicMethod_f = VarArgMethod_t.GetField("m_dynamicMethod", BindingFlags.Instance | BindingFlags.NonPublic); if (m_dynamicMethod_f == null) { throw new InvalidOperationException("Missing field 'System.Reflection.Emit.VarArgMethod.m_dynamicMethod'"); } var temp = il.DeclareLocal(VarArgMethod_t); il.Dup(); il.Stloc(temp); // temp = (VarArgMethod)value; stack: [(VarArgMethod)value] il.Ldfld(m_method_f); // stack: [((VarArgMethod)value).m_method] il.Dup(); // stack: [((VarArgMethod)value).m_method, ((VarArgMethod)value).m_method] il.Brtrue(retLabel); // if(((VarArgMethod)value).m_method != null) goto ret; stack: [((VarArgMethod)value).m_method] il.Pop(); // stack: [] il.Ldloc(temp); // stack: [(VarArgMethod)value] il.Ldfld(m_dynamicMethod_f); // stack: [((VarArgMethod)value).m_dynamicMethod] il.MarkLabel(retLabel); il.Ret(); } return((Func <object, object>)method.CreateDelegate(typeof(Func <object, object>))); }
private static Func <object, object> EmitResolveGenericMethodInfo() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(object), new[] { typeof(object) }, typeof(string), true); using (var il = new GroboIL(method)) { var GenericMethodInfo_t = typeof(DynamicMethod).Assembly.GetType("System.Reflection.Emit.GenericMethodInfo"); if (GenericMethodInfo_t == null) { throw new InvalidOperationException("Missing type 'System.Reflection.Emit.GenericMethodInfo'"); } il.Ldarg(0); // stack: [value] il.Isinst(GenericMethodInfo_t); // stack: [(GenericMethodInfo)value] var retLabel = il.DefineLabel("ret"); il.Dup(); // stack: [(GenericMethodInfo)value, (GenericMethodInfo)value] il.Brfalse(retLabel); // if(!(value is GenericMethodInfo)) goto ret; stack: [value as GenericMethodInfo] var m_methodHandle_f = GenericMethodInfo_t.GetField("m_methodHandle", BindingFlags.Instance | BindingFlags.NonPublic); if (m_methodHandle_f == null) { throw new InvalidOperationException("Missing field 'System.Reflection.Emit.GenericMethodInfo.m_methodHandle'"); } var m_context_f = GenericMethodInfo_t.GetField("m_context", BindingFlags.Instance | BindingFlags.NonPublic); if (m_context_f == null) { throw new InvalidOperationException("Missing field 'System.Reflection.Emit.GenericMethodInfo.m_context'"); } var temp = il.DeclareLocal(GenericMethodInfo_t); il.Dup(); il.Stloc(temp); // temp = (GenericMethodInfo)value; stack: [(GenericMethodInfo)value] il.Ldfld(m_methodHandle_f); // stack: [((GenericMethodInfo)value).m_methodHandle] il.Ldloc(temp); // stack: [((GenericMethodInfo)value).m_methodHandle, (GenericMethodInfo)value] il.Ldfld(m_context_f); // stack: [((GenericMethodInfo)value).m_methodHandle, ((GenericMethodInfo)value).m_context] var getMethodFromHandle_m = HackHelpers.GetMethodDefinition <int>(x => MethodBase.GetMethodFromHandle(default(RuntimeMethodHandle), default(RuntimeTypeHandle))); il.Call(getMethodFromHandle_m); // stack: [MethodBase.GetMethodFromHandle(((GenericMethodInfo)value).m_methodHandle, ((GenericMethodInfo)value).m_context)] il.MarkLabel(retLabel); il.Ret(); } return((Func <object, object>)method.CreateDelegate(typeof(Func <object, object>))); }
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(); } } }
public static TryGetValueDelegate <T> Build <T>(string[] keys, T[] values) { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(bool), new[] { typeof(T[]), typeof(string), typeof(T).MakeByRefType() }, typeof(string), true); using (var il = new GroboIL(method)) { for (int i = 0; i < keys.Length; ++i) { il.Ldarg(1); // stack: [key] il.Ldstr(keys[i]); // stack: [key, keys[i]] var nextKeyLabel = il.DefineLabel("nextKey"); il.Call(stringEqualityOperator); // stack: [key == keys[i]] il.Brfalse(nextKeyLabel); // if(key != keys[i]) goto nextKey; stack: [] il.Ldarg(2); // stack: [ref value] il.Ldarg(0); // stack: [ref value, values] il.Ldc_I4(i); // stack: [ref value, values, i] il.Ldelem(typeof(T)); // stack: [ref value, values[i]] il.Stind(typeof(T)); // value = values[i]; stack: [] il.Ldc_I4(1); // stack: [true] il.Ret(); il.MarkLabel(nextKeyLabel); } il.Ldarg(2); // stack: [ref value] if (typeof(T).IsValueType) { il.Initobj(typeof(T)); // value = default(T); stack: [] } else { il.Ldnull(); // stack: [ref value, null] il.Stind(typeof(T)); // value = null; stack: [] } il.Ldc_I4(0); // stack: [false] il.Ret(); } return((TryGetValueDelegate <T>)method.CreateDelegate(typeof(TryGetValueDelegate <T>), values)); }
private static EnumParserDelegate EmitEnumParser() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(object), new[] { typeof(Type), typeof(string), typeof(bool) }, typeof(string), true); var il = new GroboIL(method); var enumResultType = typeof(Enum).GetNestedType("EnumResult", BindingFlags.NonPublic); var enumResult = il.DeclareLocal(enumResultType); il.Ldarg(0); il.Ldarg(1); il.Ldarg(2); il.Ldloca(enumResult); il.Call(typeof(Enum).GetMethod("TryParseEnum", BindingFlags.Static | BindingFlags.NonPublic)); var returnNullLabel = il.DefineLabel("returnNull"); il.Brfalse(returnNullLabel); il.Ldloca(enumResult); il.Ldfld(enumResultType.GetField("parsedEnum", BindingFlags.Instance | BindingFlags.NonPublic)); il.Ret(); il.MarkLabel(returnNullLabel); il.Ldnull(); il.Ret(); return((EnumParserDelegate)method.CreateDelegate(typeof(EnumParserDelegate))); }