예제 #1
0
파일: Form1.cs 프로젝트: akinomyoga/afh
        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));
        }
예제 #2
0
        /// <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;
            }
        }