private static StripeHandlerFactory <T, R> GenerateStripeHandlerFactory <T, R>(Expression <Kernel <T, R> > kernel) where T : unmanaged where R : unmanaged { var ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ExprStripeHandler"), AssemblyBuilderAccess.RunAndSave); var tb = ab.DefineDynamicModule("ExprStripeHandler", "ExprStripeHandler.dll", true).DefineType("StripeHandler", TypeAttributes.Class | TypeAttributes.Public); var xmin = tb.DefineField("_xmin", typeof(int), FieldAttributes.Private); var xmax = tb.DefineField("_xmax", typeof(int), FieldAttributes.Private); var ymin = tb.DefineField("_ymin", typeof(int), FieldAttributes.Private); var ymax = tb.DefineField("_ymax", typeof(int), FieldAttributes.Private); //var delta = tb.DefineField("_delta", typeof(long), @private); //var stride = tb.DefineField("_stride", typeof(int), FieldAttributes.Private); var source = tb.DefineField("_source", typeof(UnsafeArray2d <T>), FieldAttributes.Private); var target = tb.DefineField("_target", UnsafeArray2d.GetTypeInstance <R>(), FieldAttributes.Private); ConstructorBuilder cb = BuildConstructor <T, R>(tb, xmin, xmax, ymin, ymax, source, target); MethodBuilder rm = BuildRunMethod(kernel, tb, xmin, xmax, ymin, ymax, source, target); var t = tb.CreateType(); var constructor = t.GetConstructor((from p in cb.GetParameters() select p.ParameterType).ToArray()); var runMethod = t.GetMethod(rm.Name); // there is only one method with this name ab.Save("ExprStripeHandler.dll"); return(PrepareFactory <T, R>(constructor, runMethod)); }
private static MethodBuilder BuildInstanceRun <T, R>(TypeBuilder tb, FieldInfo xmin, FieldInfo xmax, FieldInfo ymin, FieldInfo ymax, FieldInfo source, FieldInfo target, MethodBuilder staticRun) where T : unmanaged where R : unmanaged { var hss = tb.DefineMethod <Action>("Run", MethodAttributes.HideBySig | MethodAttributes.Public); var ilg = hss.GetILGenerator(); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmax); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymax); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, source); ilg.Emit(OpCodes.Call, typeof(UnsafeArray2d <T>).GetProperty(nameof(UnsafeArray2d <T> .Height)).GetGetMethod()); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, source); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymin); ilg.Emit(OpCodes.Call, typeof(UnsafeArray2d <T>).GetProperty("Item").GetGetMethod()); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, target); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymin); ilg.Emit(OpCodes.Call, UnsafeArray2d.GetTypeInstance <R>().GetProperty("Item").GetGetMethod()); ilg.Emit(OpCodes.Call, staticRun); ilg.Emit(OpCodes.Ret); return(hss); }
private static MethodBuilder BuildInstanceRun <R>(TypeBuilder tb, FieldInfo xmin, FieldInfo xmax, FieldInfo ymin, FieldInfo ymax, IEnumerable <FieldInfo> sources, FieldInfo target, MethodBuilder staticRun) { var hss = tb.DefineMethod <Action>("Run", MethodAttributes.HideBySig | MethodAttributes.Public); var ilg = hss.GetILGenerator(); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmax); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymax); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, target); ilg.Emit(OpCodes.Call, UnsafeArray2d.GetTypeInstance <R>().GetProperty(nameof(UnsafeArray2d.Height)).GetGetMethod()); foreach (var source in sources) { ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, source); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymin); ilg.Emit(OpCodes.Call, typeof(UnsafeArray2d <>).MakeGenericType(source.FieldType.GetGenericArguments()[0]).GetProperty("Item").GetGetMethod()); } ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, target); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, xmin); ilg.Emit(OpCodes.Ldarg, 0); ilg.Emit(OpCodes.Ldfld, ymin); ilg.Emit(OpCodes.Call, UnsafeArray2d.GetTypeInstance <R>().GetProperty("Item").GetGetMethod()); ilg.Emit(OpCodes.Call, staticRun); ilg.Emit(OpCodes.Ret); return(hss); }
internal static StripeMultiHandlerFactory GenerateStripeHandlerFactory <R>(LambdaExpression kernel, bool recurrent) { var ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("ExprStripeHandler"), AssemblyBuilderAccess.RunAndSave); var tb = ab.DefineDynamicModule("ExprStripeHandler", "ExprStripeHandler.dll", true).DefineType("StripeHandler", TypeAttributes.Class | TypeAttributes.Public); var xmin = tb.DefineField("_xmin", typeof(int), FieldAttributes.Private); var xmax = tb.DefineField("_xmax", typeof(int), FieldAttributes.Private); var ymin = tb.DefineField("_ymin", typeof(int), FieldAttributes.Private); var ymax = tb.DefineField("_ymax", typeof(int), FieldAttributes.Private); var sources = new List <FieldBuilder>(); foreach (var p in kernel.Parameters) { var pType = p.Type; if (pType.IsConstructedGenericType && pType.GetGenericTypeDefinition() == typeof(ICell <>)) { pType = pType.GetGenericArguments()[0]; } sources.Add(tb.DefineField("_source." + p.Name, UnsafeArray2d.GetTypeInstance(pType), FieldAttributes.Private)); } var target = tb.DefineField("_target", UnsafeArray2d.GetTypeInstance(typeof(R)), FieldAttributes.Private); if (recurrent) { sources.RemoveAt(sources.Count - 1); } ConstructorBuilder cb = BuildConstructor <R>(tb, xmin, xmax, ymin, ymax, sources, target); MethodBuilder rm = BuildRunMethod <R>(kernel, tb, xmin, xmax, ymin, ymax, sources, target, recurrent); var t = tb.CreateType(); var constructor = t.GetConstructor((from p in cb.GetParameters() select p.ParameterType).ToArray()); var runMethod = t.GetMethod(rm.Name); // there is only one method with this name ab.Save("ExprStripeHandler.dll"); return(PrepareFactory <R>(constructor, runMethod)); }
private static ConstructorBuilder BuildConstructor <R>(TypeBuilder tb, FieldInfo xmin, FieldInfo xmax, FieldInfo ymin, FieldInfo ymax, IEnumerable <FieldInfo> sources, FieldInfo target) { var paramTypes = Enumerable.Repeat(typeof(int), 4).Concat(from s in sources select s.FieldType).Append(UnsafeArray2d.GetTypeInstance <R>()).ToArray(); var c = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, paramTypes); c.DefineParameter(1, ParameterAttributes.None, "xmin"); c.DefineParameter(2, ParameterAttributes.None, "xmax"); c.DefineParameter(3, ParameterAttributes.None, "ymin"); c.DefineParameter(4, ParameterAttributes.None, "ymax"); var cilg = c.GetILGenerator(); cilg.Emit(OpCodes.Ldarg, 0); cilg.Emit(OpCodes.Ldarg, 1); cilg.Emit(OpCodes.Stfld, xmin); cilg.Emit(OpCodes.Ldarg, 0); cilg.Emit(OpCodes.Ldarg, 2); cilg.Emit(OpCodes.Stfld, xmax); cilg.Emit(OpCodes.Ldarg, 0); cilg.Emit(OpCodes.Ldarg, 3); cilg.Emit(OpCodes.Stfld, ymin); cilg.Emit(OpCodes.Ldarg, 0); cilg.Emit(OpCodes.Ldarg, 4); cilg.Emit(OpCodes.Stfld, ymax); var i = 5; foreach (var sourceField in sources) { c.DefineParameter(i, ParameterAttributes.None, sourceField.Name.Substring(1)); cilg.Emit(OpCodes.Ldarg, 0); cilg.Emit(OpCodes.Ldarg, i); cilg.Emit(OpCodes.Stfld, sourceField); i++; } c.DefineParameter(i, ParameterAttributes.None, "target"); cilg.Emit(OpCodes.Ldarg, 0); cilg.Emit(OpCodes.Ldarg, i); cilg.Emit(OpCodes.Stfld, target); cilg.Emit(OpCodes.Ret); return(c); }