コード例 #1
0
ファイル: Records.cs プロジェクト: JamesTryand/IronScheme
        static void GenerateConstructor(RecordTypeDescriptor rtd, TypeGen tg, Type parenttype)
        {
            // constructor logic
            {
                List <Type>            paramtypes = new List <Type>();
                List <FieldDescriptor> allfields  = new List <FieldDescriptor>(rtd.GetAllFields());

                int diff = allfields.Count - rtd.Fields.Length;

                foreach (FieldDescriptor var in allfields)
                {
                    paramtypes.Add(var.Type);
                }

                List <Type> parenttypes = new List <Type>();

                for (int i = 0; i < diff; i++)
                {
                    parenttypes.Add(typeof(object)); //TODO: fix this, it looks broken
                }

                if (paramtypes.Count < 9)
                {
                    CodeGen cg = tg.DefineConstructor(paramtypes.ToArray());

                    CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make",
                                                 tg.TypeBuilder, paramtypes.ToArray(), allfields.ConvertAll(x => x.Name).ToArray());


                    for (int i = 0; i < allfields.Count; i++)
                    {
                        cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name);
                    }

                    int fi = 0;

                    cg.EmitThis();


                    for (fi = 0; fi < diff; fi++)
                    {
                        cg.EmitArgGet(fi);
                        mk.EmitArgGet(fi);
                    }

                    cg.Emit(OpCodes.Call, (rtd.Parent == null ? parenttype.GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor));

                    foreach (FieldDescriptor fd in rtd.Fields)
                    {
                        cg.EmitThis();
                        cg.EmitArgGet(fi);
                        cg.EmitFieldSet(fd.field);

                        mk.EmitArgGet(fi);

                        fi++;
                    }

                    mk.EmitNew(cg.MethodBase as ConstructorInfo);
                    mk.EmitReturn();

                    cg.EmitReturn();

                    rtd.cg = cg;
                }
                else
                {
                    CodeGen cg = tg.DefineConstructor(paramtypes.ToArray());
                    CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make",
                                                 tg.TypeBuilder, new Type[] { typeof(object[]) }, new string[] { "args" });


                    for (int i = 0; i < allfields.Count; i++)
                    {
                        cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name);
                    }

                    int fi = 0;

                    cg.EmitThis();


                    for (fi = 0; fi < diff; fi++)
                    {
                        cg.EmitArgGet(fi);

                        mk.EmitArgGet(0);
                        mk.EmitConstant(fi);
                        mk.Emit(OpCodes.Ldelem, typeof(object));
                    }

                    cg.Emit(OpCodes.Call, (rtd.Parent == null ? typeof(object).GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor));

                    foreach (FieldDescriptor fd in rtd.Fields)
                    {
                        cg.EmitThis();
                        cg.EmitArgGet(fi);
                        cg.EmitFieldSet(fd.field);

                        mk.EmitArgGet(0);
                        mk.EmitConstant(fi);
                        mk.Emit(OpCodes.Ldelem, typeof(object));

                        fi++;
                    }

                    mk.EmitNew(cg.MethodBase as ConstructorInfo);
                    mk.EmitReturn();

                    cg.EmitReturn();

                    rtd.cg = cg;
                }
            }
        }
コード例 #2
0
ファイル: Records.cs プロジェクト: robertlj/IronScheme
        static void GenerateConstructor(RecordTypeDescriptor rtd, TypeGen tg, Type parenttype)
        {
            // constructor logic
              {
            List<Type> paramtypes = new List<Type>();
            List<FieldDescriptor> allfields = new List<FieldDescriptor>(rtd.GetAllFields());

            int diff = allfields.Count - rtd.Fields.Length;

            foreach (FieldDescriptor var in allfields)
            {
              paramtypes.Add(var.Type);
            }

            List<Type> parenttypes = new List<Type>();

            for (int i = 0; i < diff; i++)
            {
              parenttypes.Add(typeof(object)); //TODO: fix this, it looks broken
            }

            if (paramtypes.Count < 9)
            {
              CodeGen cg = tg.DefineConstructor(paramtypes.ToArray());

              CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make",
               tg.TypeBuilder, paramtypes.ToArray(), allfields.ConvertAll(x => x.Name).ToArray());

              for (int i = 0; i < allfields.Count; i++)
              {
            cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name);
              }

              int fi = 0;

              cg.EmitThis();

              for (fi = 0; fi < diff; fi++)
              {
            cg.EmitArgGet(fi);
            mk.EmitArgGet(fi);
              }

              // improve get constructor to look for protected constructors too
              cg.Emit(OpCodes.Call, (rtd.Parent == null ? parenttype.GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor));

              foreach (FieldDescriptor fd in rtd.Fields)
              {
            cg.EmitThis();
            cg.EmitArgGet(fi);
            cg.EmitFieldSet(fd.field);

            mk.EmitArgGet(fi);

            fi++;
              }

              mk.EmitNew(cg.MethodBase as ConstructorInfo);
              mk.EmitReturn();

              cg.EmitReturn();

              rtd.cg = cg;
            }
            else
            {

              CodeGen cg = tg.DefineConstructor(paramtypes.ToArray());
              CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make",
               tg.TypeBuilder, new Type[] { typeof(object[]) }, new string[] { "args" });

              for (int i = 0; i < allfields.Count; i++)
              {
            cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name);
              }

              int fi = 0;

              cg.EmitThis();

              for (fi = 0; fi < diff; fi++)
              {
            cg.EmitArgGet(fi);

            mk.EmitArgGet(0);
            mk.EmitConstant(fi);
            mk.Emit(OpCodes.Ldelem, typeof(object));
              }

              cg.Emit(OpCodes.Call, (rtd.Parent == null ? typeof(object).GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor));

              foreach (FieldDescriptor fd in rtd.Fields)
              {
            cg.EmitThis();
            cg.EmitArgGet(fi);
            cg.EmitFieldSet(fd.field);

            mk.EmitArgGet(0);
            mk.EmitConstant(fi);
            mk.Emit(OpCodes.Ldelem, typeof(object));

            fi++;
              }

              mk.EmitNew(cg.MethodBase as ConstructorInfo);
              mk.EmitReturn();

              cg.EmitReturn();

              rtd.cg = cg;
            }
              }
        }