Exemplo n.º 1
0
        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;
                }
            }
        }
Exemplo n.º 2
0
    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;
        }
      }
    }