コード例 #1
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
        /// <summary>
        /// brtrue 命令を出力します。スタックのトップが真である時に分岐を行います。
        /// </summary>
        /// <param name="label">分岐先のラベルを指定します。</param>
        public void EmitBrtrue(Emit::Label label)
        {
            gen.Emit(Emit::OpCodes.Brtrue, label);

            // ↓は label との距離が分からないので使えるかどうか分からない。
            // gen.Emit(Emit::OpCodes.Brtrue_S,label);
        }
コード例 #2
0
            public bool Emit(afh.Reflection.ILGeneratorHelper gh, System.Reflection.Emit.Label label)
            {
                Emit::Label l = gh.CreateLabel();

                gh.EmitLdarg(1);
                gh.EmitLdc(this.c1);
                gh.EmitBltUnS(l);
                gh.EmitLdarg(1);
                gh.EmitLdc(this.c2);
                gh.EmitBleUn(label);
                gh.MarkLabel(l);
                return(true);
            }
コード例 #3
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));
        }
コード例 #4
0
            private System.Predicate <char> CreateHandler(
                bool positive, IClassHandler[] handlers, bool[] issub,
                out IClassHandler[] child
                )
            {
                int[] borders;
                {
                    Gen::List <int> borders_l = new System.Collections.Generic.List <int>();
                    bool            current   = true;
                    for (int i = 0; i < issub.Length; i++)
                    {
                        if (issub[i] == current)
                        {
                            continue;
                        }
                        borders_l.Add(i);                         // *
                        current = issub[i];
                    }
                    // issub: [F T T T F F T T F T F F F T T T ]
                    // brdrs:    *     *   *   * * *     *     @

                    borders_l.Add(issub.Length);                     // @
                    borders = borders_l.ToArray();
                }

                afh.Reflection.DynamicMethodCreater <CompiledClassHandler, System.Predicate <char> > gh
                    = new afh.Reflection.DynamicMethodCreater <CompiledClassHandler, System.Predicate <char> >("<generated>", false);

                Gen::List <IClassHandler> child_l = new Gen::List <IClassHandler>();

                Emit::Label label = gh.CreateLabel();

                for (int k = 0, kM = borders.Length - 1; k < kM; k++)
                {
                    for (int i = borders[k]; i < borders[k + 1]; i++)
                    {
                        //-- それぞれのハンドラに応じた処理
                        // 判定陽性 → goto label;
                        // 判定陰性 → その儘次へ流れる
                        if (!handlers[i].Emit(gh, label))
                        {
                            // child リストから呼び出す場合
                            int iChild = child_l.Count;
                            child_l.Add(handlers[i]);

                            // (s1)= this.child[iChild]
                            gh.EmitLdarg(0);
                            gh.EmitLdfld(typeof(CompiledClassHandler), "child", false, true);
                            gh.EmitLdc(iChild);
                            gh.EmitLdelem(typeof(IClassHandler));

                            // if((s1).Judge(c))goto label;
                            gh.EmitLdarg(1);
                            gh.EmitCall(handlers[i].GetType(), false, false, "Judge", typeof(char));
                            gh.EmitBrtrue(label);
                        }
                    }

                    // もう終わる時
                    if (k + 1 == kM)
                    {
                        break;
                    }
                    else
                    {
                        Emit::Label newlabel = gh.CreateLabel();
                        gh.EmitBr(newlabel);
                        gh.MarkLabel(label);
                        label = newlabel;

                        positive = !positive;
                    }
                }
                gh.EmitLdc(!positive);
                gh.EmitRet();
                gh.MarkLabel(label);
                gh.EmitLdc(positive);
                gh.EmitRet();

                child = child_l.ToArray();

                return(gh.Instantiate(this));
            }
コード例 #5
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// ラベルを出力します。
 /// </summary>
 /// <param name="label">出力するラベルを指定します。</param>
 public void MarkLabel(Emit::Label label)
 {
     gen.MarkLabel(label);
 }
コード例 #6
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// bge.s 命令を出力します。スタックの上の二つの値を符号付き整数として比較して、
 /// 一つ目の値の方が二つ目の値以上の時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBgeS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Bge_S, label);
 }
コード例 #7
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// blt.s 命令を出力します。スタックの上の二つの値を符号付き整数として比較して、
 /// 一つ目の値の方が二つ目の値よりも小さい時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBltS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Blt_S, label);
 }
コード例 #8
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// bgt.un.s 命令を出力します。スタックの上の二つの値を符号無し整数として比較して、
 /// 一つ目の値の方が二つ目の値よりも大きい時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBgtUnS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Bgt_Un_S, label);
 }
コード例 #9
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// ble.un.s 命令を出力します。スタックの上の二つの値を符号無し整数として比較して、
 /// 一つ目の値の方が二つ目の値以下の時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBleUnS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Ble_Un_S, label);
 }
コード例 #10
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// bne 命令を出力します。スタックの上の二つの値が異なる時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBneS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Bne_Un_S, label);
 }
コード例 #11
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// beq 命令を出力します。スタックの上の二つの値が等しい時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBeqS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Beq_S, label);
 }
コード例 #12
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// br 命令を出力します。無条件で、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBrS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Br_S, label);
 }
コード例 #13
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// brfalse 命令を出力します。スタックのトップが偽である時に、近くに分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBrfalseS(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Brfalse_S, label);
 }
コード例 #14
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// ble 命令を出力します。スタックの上の二つの値を符号付き整数として比較して、
 /// 一つ目の値の方が二つ目の値以下の時に分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBle(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Ble, label);
 }
コード例 #15
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// bge.un 命令を出力します。スタックの上の二つの値を符号無し整数として比較して、
 /// 一つ目の値の方が二つ目の値以上の時に分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBgeUn(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Bge_Un, label);
 }
コード例 #16
0
ファイル: afh.Reflection.cs プロジェクト: akinomyoga/afh
 /// <summary>
 /// blt.un 命令を出力します。スタックの上の二つの値を符号無し整数として比較して、
 /// 一つ目の値の方が二つ目の値よりも小さい時に分岐を行います。
 /// </summary>
 /// <param name="label">分岐先のラベルを指定します。</param>
 public void EmitBltUn(Emit::Label label)
 {
     gen.Emit(Emit::OpCodes.Blt_Un, label);
 }