public BenchMethod(Ref::MethodInfo minfo, BenchMethodAttribute attr) { this.minfo = minfo; this.attr = attr; Emit::DynamicMethod m = new Emit::DynamicMethod( "bench", typeof(TimeSpan), new System.Type[] { typeof(int) }, minfo.DeclaringType ); // // 宣言 // Emit::ILGenerator ilgen = m.GetILGenerator(); System.Type type_dt = typeof(System.DateTime); Emit::LocalBuilder loc_start = ilgen.DeclareLocal(type_dt); Emit::LocalBuilder loc_end = ilgen.DeclareLocal(type_dt); Emit::LocalBuilder loc_i = ilgen.DeclareLocal(typeof(int)); Ref::MethodInfo m_get_Now = type_dt.GetMethod("get_Now"); Ref::MethodInfo m_op_Subtraction = type_dt.GetMethod("op_Subtraction", new System.Type[] { type_dt, type_dt }); Emit::Label label_loopC = ilgen.DefineLabel(); Emit::Label label_loopJ = ilgen.DefineLabel(); // // ロジック // //-- pro ilgen.Emit(Emit::OpCodes.Call, m_get_Now); ilgen.Emit(Emit::OpCodes.Stloc, loc_start); //-- loop ilgen.Emit(Emit::OpCodes.Ldc_I4_0); ilgen.Emit(Emit::OpCodes.Dup); // ilgen.Emit(Emit::OpCodes.Stloc, loc_i); ilgen.Emit(Emit::OpCodes.Br_S, label_loopJ); ilgen.MarkLabel(label_loopC); ilgen.Emit(Emit::OpCodes.Call, minfo); if (minfo.ReturnType != typeof(void)) { ilgen.Emit(Emit::OpCodes.Pop); } ilgen.Emit(Emit::OpCodes.Ldloc, loc_i); ilgen.Emit(Emit::OpCodes.Ldc_I4_1); ilgen.Emit(Emit::OpCodes.Add); ilgen.Emit(Emit::OpCodes.Dup); // ilgen.Emit(Emit::OpCodes.Stloc, loc_i); ilgen.MarkLabel(label_loopJ); //ilgen.Emit(Emit::OpCodes.Ldloc,loc_i); ilgen.Emit(Emit::OpCodes.Ldarg_0); ilgen.Emit(Emit::OpCodes.Blt_S, label_loopC); //-- epi ilgen.Emit(Emit::OpCodes.Call, m_get_Now); ilgen.Emit(Emit::OpCodes.Stloc, loc_end); ilgen.Emit(Emit::OpCodes.Ldloc, loc_end); ilgen.Emit(Emit::OpCodes.Ldloc, loc_start); ilgen.Emit(Emit::OpCodes.Call, m_op_Subtraction); ilgen.Emit(Emit::OpCodes.Ret); this.meth = (MeasureTime)m.CreateDelegate(typeof(MeasureTime)); }
/// <summary> /// 指定した番号の引数をスタックに積みます。 /// </summary> /// <param name="index">引数の番号を指定します。</param> public void EmitLdarg(short index) { if (index < 0) { throw new System.ArgumentOutOfRangeException("index", "ldarg: 引数の番号は 0 以上である必要があります。"); } switch (index) { case 0: gen.Emit(Emit::OpCodes.Ldarg_0); break; case 1: gen.Emit(Emit::OpCodes.Ldarg_1); break; case 2: gen.Emit(Emit::OpCodes.Ldarg_2); break; case 3: gen.Emit(Emit::OpCodes.Ldarg_3); break; default: if (index <= 225) { gen.Emit(Emit::OpCodes.Ldarg_S, (byte)index); } else { gen.Emit(Emit::OpCodes.Ldarg, index); } break; } }