コード例 #1
0
ファイル: ForIn.cs プロジェクト: mayatforest/Refractor
        internal override void Emit(EmitContext ec)
        {
            ILGenerator ig     = ec.ig;
            bool        varStm = lhs is VariableStatement;
            object      var    = null;

            if (varStm)
            {
                VariableStatement stm = (VariableStatement)lhs;
                ig.Emit(OpCodes.Ldnull);
                var = TypeManager.Get(((VariableDeclaration)stm.var_decls [0]).id);
                set_builder(ig, var);
            }
            if (obj != null)
            {
                obj.Emit(ec);
            }

            CodeGenerator.load_engine(InFunction, ig);


            Type convert = typeof(Convert);

            ig.Emit(OpCodes.Call, convert.GetMethod("ToForInObject"));
            ig.Emit(OpCodes.Call, typeof(ForIn).GetMethod("JScriptGetEnumerator"));
            Type         ienumerator = typeof(IEnumerator);
            LocalBuilder iter        = ig.DeclareLocal(ienumerator);
            LocalBuilder current     = ig.DeclareLocal(typeof(object));

            ig.Emit(OpCodes.Stloc, iter);

            Label init_loop = ig.DefineLabel();
            Label move_next = ig.DefineLabel();
            Label exit      = ig.DefineLabel();

            ig.Emit(OpCodes.Br, move_next);
            ig.MarkLabel(init_loop);

            if (body != null)
            {
                body.Emit(ec);
            }

            ig.MarkLabel(move_next);

            ig.Emit(OpCodes.Ldloc, iter);
            ig.Emit(OpCodes.Callvirt, ienumerator.GetMethod("MoveNext"));

            ig.Emit(OpCodes.Brfalse, exit);

            ig.Emit(OpCodes.Ldloc, iter);
            ig.Emit(OpCodes.Callvirt, ienumerator.GetProperty("Current").GetGetMethod());
            ig.Emit(OpCodes.Stloc, current);
            ig.Emit(OpCodes.Ldloc, current);

            if (varStm)
            {
                set_builder(ig, var);
            }
            else
            {
                if (lhs is Expression)
                {
                    AST ast = ((Expression)lhs).Last;
                    if (ast is Identifier)
                    {
                        ((Identifier)ast).EmitStore(ec);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            ig.Emit(OpCodes.Br, init_loop);
            ig.MarkLabel(exit);
        }