protected override bool EmitInternal(LambdaExpression node, EmittingContext context, GroboIL.Label returnDefaultValueLabel, ResultType whatReturn, bool extend, out Type resultType) { var parameterTypes = node.Parameters.Select(parameter => parameter.Type).ToArray(); Type[] constantTypes; var compiledLambda = CompileAndLoadConstants(node, context, out constantTypes); var il = context.Il; Type rawSubLambdaType; if (!Extensions.IsMono) { context.LoadCompiledLambdaPointer(compiledLambda); rawSubLambdaType = typeof(IntPtr); } else { rawSubLambdaType = Extensions.GetDelegateType(constantTypes.Concat(parameterTypes).ToArray(), node.ReturnType); context.LoadCompiledLambda(compiledLambda); il.Castclass(rawSubLambdaType); } resultType = Extensions.GetDelegateType(parameterTypes, node.ReturnType); var types = constantTypes.Concat(new[] { rawSubLambdaType }).ToArray(); var module = (ModuleBuilder)(context.TypeBuilder == null ? null : context.TypeBuilder.Module); var subLambdaInvoker = DynamicMethodInvokerBuilder.BuildDynamicMethodInvoker(module, constantTypes, node.ReturnType, parameterTypes); il.Newobj(subLambdaInvoker.GetConstructor(types)); il.Ldftn(subLambdaInvoker.GetMethod("Invoke")); il.Newobj(resultType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); return(false); }
public unsafe void TestWriteAssemblerCode() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(object), new[] { typeof(object) }, typeof(string), true); using (var il = new GroboIL(method, false)) { il.Ldarg(0); il.Isinst(typeof(int?)); il.Ret(); } method.CreateDelegate(typeof(Func <object, object>)); var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method); var b = (byte *)pointer; //var zzz = Convert.FromBase64String(@"VldVU0FSTInOSItsJFhIi3wkYEGJyonRRInDRInQVQ8oBg8oZhAPKMgPKOwPKNAPKPQPKNgPKPwPWUUAD1llEA9ZTTAPWW1AD1lVYA9ZdXAPWZ2QAAAAD1m9oAAAAPIPfMHyD3zl8g980/IPfPfyD3zC8g985g9Y4A8oRiAPKMgPKNAPKNgPWUUgD1lNUA9ZlYAAAAAPWZ2wAAAA8g98wfIPfNPyD3zCD1jgD1ilwAAAAA8rJ0iBxdAAAABIg8cQ/8gPhVf///9Ig8YwXf/LD4VG////Z0ONBFJnQY0EgsHgBEiYSAHF/8kPhSn///9BWltdX17D"); var zzz = Convert.FromBase64String(@"VldVU0FSTInOSItsJFBIi3wkWEGJyonRRInDRInQVQ8oBg8oZhAPKMgPKOwPKNAPKPQPKNgPKPwPWUUAD1llEA9ZTTAPWW1AD1lVYA9ZdXAPWZ2QAAAAD1m9oAAAAPIPfMHyD3zl8g980/IPfPfyD3zC8g985g9Y4A8oRiAPKMgPKNAPKNgPWUUgD1lNUA9ZlYAAAAAPWZ2wAAAA8g98wfIPfNPyD3zCD1jgD1ilwAAAAA8rJ0iBxdAAAABIg8cQ/8gPhVf///9Ig8YwXf/LD4VG////Z0ONBFJnQY0EgsHgBEiYSAHF/8kPhSn///9BWltdX17D"); fixed(byte *z = &zzz[0]) { b = z; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { Console.Write(string.Format("{0:X2} ", *b++)); } Console.WriteLine(); } } }
public unsafe void TestWriteAssemblerCode3() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(IntPtr), typeof(int) }, typeof(string), true); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); if (IntPtr.Size == 8) { il.Emit(OpCodes.Ldc_I8, 0x123456789ABCDEF1); } else { il.Emit(OpCodes.Ldc_I4, 0x12345678); } il.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, typeof(void), new[] { typeof(IntPtr), typeof(int) }); il.Emit(OpCodes.Ret); method.CreateDelegate(typeof(Action <IntPtr, int>)); var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method); var b = (byte *)pointer; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { Console.Write(string.Format("{0:X2} ", *b++)); } Console.WriteLine(); } Console.WriteLine(TestStind_i4(123456678)[1]); }
public unsafe void TestWriteAssemblerCode2() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(IntPtr), Type.EmptyTypes, typeof(string), true); var il = method.GetILGenerator(); var ptr = new IntPtr(0x40100C); if (IntPtr.Size == 4) { il.Emit(OpCodes.Ldc_I4, ptr.ToInt32()); } else { il.Emit(OpCodes.Ldc_I8, ptr.ToInt64()); } il.Emit(OpCodes.Conv_U); il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, typeof(void), Type.EmptyTypes, null); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ret); method.CreateDelegate(typeof(Func <IntPtr>)); var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method); var b = (byte *)pointer; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { Console.Write(string.Format("{0:X2} ", *b++)); } Console.WriteLine(); } }
public unsafe void TestWriteAssemblerCode0() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(double) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Conv <int>(); il.Ret(); } var func = (Func <double, int>)method.CreateDelegate(typeof(Func <double, int>)); Console.WriteLine(func(3000000000)); var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method); var b = (byte *)pointer; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { Console.Write(string.Format("{0:X2} ", *b++)); } Console.WriteLine(); } }
private ITest BuildCalli() { var action = Build(); var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public); var pointerField = typeBuilder.DefineField("pointer", typeof(IntPtr), FieldAttributes.Private | FieldAttributes.InitOnly); var delegateField = typeBuilder.DefineField("delegate", typeof(Delegate), FieldAttributes.Private | FieldAttributes.InitOnly); var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] { typeof(IntPtr), typeof(Delegate) }); var il = new GroboIL(constructor); il.Ldarg(0); il.Ldarg(1); il.Stfld(pointerField); il.Ldarg(0); il.Ldarg(2); il.Stfld(delegateField); il.Ret(); var method = typeBuilder.DefineMethod("DoNothing", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), Type.EmptyTypes); il = new GroboIL(method); il.Ldarg(0); il.Ldfld(pointerField); il.Calli(CallingConventions.Standard, typeof(void), Type.EmptyTypes); il.Ret(); typeBuilder.DefineMethodOverride(method, typeof(ITest).GetMethod("DoNothing")); typeBuilder.AddInterfaceImplementation(typeof(ITest)); var type = typeBuilder.CreateType(); return((ITest)Activator.CreateInstance(type, new object[] { DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor((DynamicMethod)action.Item2), action.Item1 })); }
public unsafe void TestWriteAssemblerCode4() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(int), new[] { typeof(int), typeof(int), typeof(int), typeof(int) }, typeof(string), true); var il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); byte[] marker; if (IntPtr.Size == 8) { const long addr = 0x123456789ABCDEF1; marker = BitConverter.GetBytes(addr); il.Emit(OpCodes.Ldc_I8, addr); } else { const int addr = 0x12345678; marker = BitConverter.GetBytes(addr); il.Emit(OpCodes.Ldc_I4, addr); } il.EmitCalli(OpCodes.Calli, CallingConventions.Standard, typeof(int), new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), }, null); il.Emit(OpCodes.Ret); var func = (Func <int, int, int, int, int>)method.CreateDelegate(typeof(Func <int, int, int, int, int>)); var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method); Console.WriteLine("{0:X}", pointer.ToInt64()); //Replace((byte*)pointer, marker); var b = (byte *)pointer; for (int i = 0; i < 20; ++i) { for (int j = 0; j < 10; ++j) { Console.Write(string.Format("{0:X2} ", *b++)); } Console.WriteLine(); } var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < 1000000001; ++i) { func(i, i, i, i); } var elapsed = stopwatch.Elapsed; Console.WriteLine(elapsed); }
public void LoadCompiledLambdaPointer(CompiledLambda compiledLambda) { if (TypeBuilder != null) { Il.Ldftn(compiledLambda.Method); } else { var stopwatch = Stopwatch.StartNew(); var pointer = DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor((DynamicMethod)compiledLambda.Method); LambdaCompiler.TotalJITCompilationTime += stopwatch.Elapsed.TotalSeconds; Il.Ldc_IntPtr(pointer); } }
private static Tuple <Delegate, IntPtr> EmitFieldExtractor <T, TValue>(FieldInfo field) { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(TValue), new[] { typeof(T) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); // stack: [list] il.Ldfld(field); il.Ret(); } return(new Tuple <Delegate, IntPtr>((Func <T, TValue>)method.CreateDelegate(typeof(Func <T, TValue>)), DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method))); }
private static Tuple <Delegate, IntPtr> EmitListResizer <T>() { var method = new DynamicMethod(Guid.NewGuid().ToString(), typeof(void), new[] { typeof(List <T>), typeof(int) }, typeof(string), true); using (var il = new GroboIL(method)) { il.Ldarg(0); // stack: [list] il.Ldarg(1); // stack: [list, arrayIndex] il.Ldc_I4(1); // stack: [list, arrayIndex, 1] il.Add(); // stack: [list, arrayIndex + 1] il.Call(typeof(List <T>).GetMethod("EnsureCapacity", BindingFlags.Instance | BindingFlags.NonPublic)); // list.EnsureCapacity(arrayIndex + 1); stack: [] il.Ldarg(0); // stack: [list] il.Ldarg(1); // stack: [list, arrayIndex] il.Ldc_I4(1); // stack: [list, arrayIndex, 1] il.Add(); // stack: [list, arrayIndex + 1] il.Stfld(typeof(List <T>).GetField("_size", BindingFlags.Instance | BindingFlags.NonPublic)); // list.Count = arrayIndex + 1; stack: [] il.Ret(); } return(new Tuple <Delegate, IntPtr>((Action <List <T>, int>)method.CreateDelegate(typeof(Action <List <T>, int>)), DynamicMethodInvokerBuilder.DynamicMethodPointerExtractor(method))); }