* PEAPI.cs: Don't build custom attributes twice.
[mono.git] / mcs / class / PEAPI / PEAPI.cs
index 32a28ebd4779141a91faf5985cba2e51b8241ffa..9c28a49496c3d4c6d529453bd9b02420060fbe7d 100644 (file)
@@ -95,6 +95,25 @@ namespace PEAPI
     public TypeSignatureException(string msg) : base(msg) { }\r
   }\r
 \r
+                   public class ClassRefInst : Type {\r
+
+                          private Class type;
+                          private bool is_value;
+\r
+            public ClassRefInst (Class type, bool is_value) : base (0x12) {\r
+                    this.type = type;
+                    this.is_value = is_value;
+                    if (is_value)
+                            typeIndex = 0x11;
+                    tabIx = MDTable.TypeSpec;\r
+            }\r
+\r
+            internal sealed override void TypeSig(MemoryStream str) {\r
+                    str.WriteByte (GetTypeIndex());
+                    MetaData.CompressNum (type.TypeDefOrRefToken(), str);\r
+            }
+    }\r
+                  
   public class MVar : Type {\r
 \r
             private int index;\r
@@ -299,7 +318,7 @@ namespace PEAPI
   {\r
     ushort majorVer, minorVer, buildNo, revisionNo;\r
     uint flags;\r
-    HashAlgorithm hashAlgId = HashAlgorithm.None;\r
+    uint hashAlgId;
     uint keyIx = 0, cultIx = 0;\r
     \r
     internal Assembly(string name, MetaData md) : base(name,md) {\r
@@ -317,7 +336,7 @@ namespace PEAPI
     /// <param name="hash">Hash Algorithm</param>\r
     /// <param name="cult">Culture</param>\r
     public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo, \r
-                              byte[] key, HashAlgorithm hash, string cult) {\r
+                              byte[] key, uint hash, string cult) {\r
       majorVer = (ushort)majVer;\r
       minorVer = (ushort)minVer;\r
       buildNo = (ushort)bldNo;\r
@@ -362,10 +381,16 @@ namespace PEAPI
 \r
   }     \r
   /**************************************************************************/  \r
+
+        public interface IExternRef  {
+                ClassRef AddClass(string nsName, string name);
+                ClassRef AddValueClass(string nsName, string name);
+        }
+        
         /// <summary>\r
         /// A reference to an external assembly (.assembly extern)\r
         /// </summary>\r
-        public class AssemblyRef : ResolutionScope\r
+        public class AssemblyRef : ResolutionScope, IExternRef
         {\r
     private ushort major, minor, build, revision;\r
     uint flags, keyIx, hashIx, cultIx;\r
@@ -498,7 +523,7 @@ namespace PEAPI
       }\r
       return 0;\r
     }\r
\r
+
         }\r
   /**************************************************************************/  \r
 \r
@@ -643,8 +668,15 @@ namespace PEAPI
   /// <summary>\r
   /// CIL branch instructions\r
   /// </summary>\r
-  public enum BranchOp {br = 0x2B, brfalse, brtrue, beq, bge, bgt, ble, blt,\r
-    bne_un, bge_un, bgt_un, ble_un, blt_un, leave = 0xDE }\r
+  public enum BranchOp {
+          // short branches
+          br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
+          ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
+          // long branches
+          br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,\r
+          bne_un, bge_un, bgt_un, ble_un, blt_un,
+
+          leave = 0xDD, leave_s }\r
 \r
   /// <summary>\r
   /// Index for all the tables in the meta data\r
@@ -993,8 +1025,15 @@ namespace PEAPI
     /// <param name="str">the string value</param>\r
     public void ldstr(string str) {\r
       AddToBuffer(new StringInstr(0x72,str));\r
-    }\r
-\r
+    }
+
+          /// <summary>
+          /// Add the load string instruction
+          /// </summary>
+          public void ldstr (byte[] str) {
+                  AddToBuffer (new StringInstr (0x72, str));
+          }
+          
     /// <summary>\r
     /// Add the calli instruction\r
     /// </summary>\r
@@ -1331,6 +1370,13 @@ namespace PEAPI
             numExceptClauses += (uint)tryBlock.NumHandlers();\r
             if (tryBlock.isFat()) fatExceptionFormat = true;\r
           }\r
+
+          uint data_size = ExHeaderSize + numExceptClauses *
+                 (fatExceptionFormat ? FatExClauseSize : SmlExClauseSize);
+
+          if (data_size > 256)
+                  fatExceptionFormat = true;
+                  
           // Console.WriteLine("numexceptclauses = " + numExceptClauses);\r
           if (fatExceptionFormat) {\r
             // Console.WriteLine("Fat exception format");\r
@@ -1775,7 +1821,12 @@ namespace PEAPI
       fields.Add(field);\r
       return field;\r
     }\r
-\r
+
+    public void SetFieldOrder (ArrayList fields)
+    {
+            this.fields = fields;
+    }
+
     /// <summary>\r
     /// Add a method to this class\r
     /// </summary>\r
@@ -1942,7 +1993,6 @@ namespace PEAPI
         md.AddToTable(MDTable.PropertyMap,new MapElem(this,\r
                           ((Property)properties[0]).Row,MDTable.Property));\r
       }\r
-      DoCustomAttributes (md);\r
       // Console.WriteLine("End of building tables");\r
       done = true;\r
     }\r
@@ -2302,25 +2352,25 @@ namespace PEAPI
 \r
     public IntConst(sbyte val) {\r
       this.val = val;\r
-      size = 8;\r
+      size = 1;\r
       type = PrimitiveType.Int8;\r
     }\r
 \r
     public IntConst(short val) {\r
       this.val = val;\r
-      size = 16;\r
+      size = 2;\r
       type = PrimitiveType.Int16;\r
     }\r
 \r
     public IntConst(int val) {\r
       this.val = val;\r
-      size = 32;\r
+      size = 4;\r
       type = PrimitiveType.Int32;\r
     }\r
 \r
     public IntConst(long val) {\r
       this.val = val;\r
-      size = 64;\r
+      size = 8;\r
       type = PrimitiveType.Int64;\r
     }\r
 \r
@@ -2353,22 +2403,22 @@ namespace PEAPI
 \r
     public UIntConst(sbyte val) {\r
       this.val = val;\r
-      size = 8;\r
+      size = 1;\r
       type = PrimitiveType.UInt8;\r
     }\r
     public UIntConst(short val) {\r
       this.val = val;\r
-      size = 16;\r
+      size = 2;\r
       type = PrimitiveType.UInt16;\r
     }\r
     public UIntConst(int val) {\r
       this.val = val;\r
-      size = 32;\r
+      size = 4;\r
       type = PrimitiveType.UInt32;\r
     }\r
     public UIntConst(long val) {\r
       this.val = val;\r
-      size = 64;\r
+      size = 8;\r
       type = PrimitiveType.UInt64;\r
     }\r
 \r
@@ -2406,8 +2456,9 @@ namespace PEAPI
     }\r
 \r
     internal sealed override uint GetBlobIndex(MetaData md) {\r
-      if (!addedToBlobHeap) {\r
-        blobIndex = md.AddToBlobHeap(val);\r
+      if (!addedToBlobHeap) {
+        byte [] b = Encoding.Unicode.GetBytes (val);
+        blobIndex = md.AddToBlobHeap(b);\r
         addedToBlobHeap = true;\r
       }\r
       return blobIndex;\r
@@ -2599,7 +2650,7 @@ namespace PEAPI
 \r
     internal sealed override void BuildTables(MetaData md) {\r
       BinaryWriter bw = new BinaryWriter(new MemoryStream());\r
-      bw.Write((ushort)1);\r
+      bw.Write(byteVal);\r
       md.AddToTable(MDTable.CustomAttribute, this);\r
       MemoryStream str = (MemoryStream)bw.BaseStream;\r
       valIx = md.AddToBlobHeap(str.ToArray());\r
@@ -2872,6 +2923,7 @@ namespace PEAPI
     //private static readonly uint PInvokeImpl = 0x2000;\r
     private static readonly ushort HasFieldMarshal = 0x1000;\r
     private static readonly ushort HasFieldRVA = 0x100;\r
+    private static readonly ushort HasDefault = 0x8000;
 \r
     FieldRVA rva;\r
     ConstantElem constVal;\r
@@ -2902,6 +2954,7 @@ namespace PEAPI
     /// <param name="val">the value for the field</param>\r
     public void AddValue(Constant val) {\r
       constVal = new ConstantElem(this,val);\r
+      flags |= HasDefault;
     }\r
 \r
     /// <summary>\r
@@ -3326,12 +3379,12 @@ if (rsrc != null)
                                 sdata.SetSize(NumToAlign(sdata.Tide(),fileAlign));\r
                                 sdata.SetOffset(offset);\r
         sdata.SetRVA(rva);\r
-        offset += sdata.Size();\r
+        offset += sdata.Size();
         rva = GetNextSectStart(rva,sdata.Tide());\r
                                 initDataSize += sdata.Size();\r
       }\r
       if (rsrc != null) { \r
-                                rsrc.SetSize(NumToAlign(rsrc.Tide(),fileAlign));\r
+                     rsrc.SetSize(NumToAlign(rsrc.Tide(),fileAlign));\r
                                 rsrc.SetOffset(offset);\r
         rsrc.SetRVA(rva);\r
         offset += rsrc.Size();\r
@@ -3433,9 +3486,13 @@ if (rsrc != null)
      }\r
 \r
     private void WriteSDataSection() {\r
+      long size = sdata.Size ();
+      long start = BaseStream.Position;
       for (int i=0; i < data.Count; i++) {\r
         ((DataConstant)data[i]).Write(this);\r
-      }\r
+      }
+      while (BaseStream.Position < (start + size))
+              Write ((byte) 0);
     }\r
 \r
                 private void WriteRsrcSection() {\r
@@ -3605,13 +3662,13 @@ if (rsrc != null)
         /// </summary>\r
         public class FileRef : MetaDataElement\r
         {\r
-    private static readonly uint HasMetaData = 0x1;\r
+    private static readonly uint NoMetaData = 0x1;\r
     uint nameIx = 0, hashIx = 0;\r
     uint flags = 0;\r
 \r
     internal FileRef(string name, byte[] hashBytes, bool metaData,\r
                       bool entryPoint, MetaData md) {\r
-      if (metaData) flags = HasMetaData;\r
+      if (!metaData) flags = NoMetaData;\r
       if (entryPoint) md.SetEntryPoint(this);\r
       nameIx = md.AddToStringsHeap(name);\r
       hashIx = md.AddToBlobHeap(hashBytes);\r
@@ -3620,7 +3677,7 @@ if (rsrc != null)
 \r
     internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,\r
                       bool entryPoint, MetaData md) {\r
-      if (metaData) flags = HasMetaData;\r
+      if (!metaData) flags = NoMetaData;\r
       if (entryPoint) md.SetEntryPoint(this);\r
       this.nameIx = nameIx;\r
       hashIx = md.AddToBlobHeap(hashBytes);\r
@@ -3836,16 +3893,25 @@ if (rsrc != null)
         }\r
 \r
   internal class StringInstr : Instr {\r
-    string val;\r
+    string val;
+          byte[] bval;                                                  
     uint strIndex;\r
 \r
     internal StringInstr(int inst, string str) : base(inst) {\r
       val = str;  \r
       size += 4;\r
-    }\r
-\r
-    internal sealed override bool Check(MetaData md) {\r
-      strIndex = md.AddToUSHeap(val);\r
+    }
+
+          internal StringInstr (int inst, byte[] str) : base (inst) {
+                  bval = str;
+                  size += 4;
+          }
+                   
+    internal sealed override bool Check(MetaData md) {
+            if (val != null)
+                    strIndex = md.AddToUSHeap(val);
+            else
+                    strIndex = md.AddToUSHeap (bval);
       return false;\r
     }\r
 \r
@@ -3940,20 +4006,18 @@ if (rsrc != null)
       dest = dst;\r
       dest.AddBranch(this);\r
       size++;\r
+
+      if (inst >= (int) BranchOp.br && inst != (int) BranchOp.leave_s) {
+              shortVer = false;
+              size += 3;
+      }
     }\r
 \r
     internal sealed override bool Check(MetaData md) {\r
       target = (int)dest.GetLabelOffset() - (int)(offset + size);\r
-      if (shortVer && ((target < minByteVal) || (target > maxByteVal))) {\r
-        if (instr < (int)BranchOp.leave) instr += longInstrOffset;\r
-        else instr--;\r
-        shortVer = false;\r
-        size += 3;\r
-        return true;\r
-      }\r
-      return false;\r
+      return false;
     }\r
-\r
+
                 internal sealed override void Write(FileImage output) {\r
                         base.Write(output);\r
                         if (shortVer)\r
@@ -4360,7 +4424,8 @@ if (rsrc != null)
     public MSCorLib mscorlib;\r
     private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];\r
     long mdStart;\r
-\r
+                private ArrayList cattr_list;
+                
     internal MetaData(FileImage file) {\r
       // tilde = new MetaDataStream(tildeName,false,0);\r
       this.file = file;\r
@@ -4390,7 +4455,6 @@ if (rsrc != null)
     }\r
 \r
     internal uint Size() {\r
-      //Console.WriteLine("metaData size = " + metaDataSize);\r
       return metaDataSize;\r
     }\r
 \r
@@ -4401,67 +4465,78 @@ if (rsrc != null)
     internal uint AddToUSHeap(string str) {\r
       if (str == null) return 0;\r
       return us.Add(str,true);\r
-   }\r
-\r
+   }
+
+                internal uint AddToUSHeap(byte[] str) {
+                        if (str == null) return 0;
+                        return us.Add (str, true);
+                }
+                                
     internal uint AddToStringsHeap(string str) {\r
       if ((str == null) || (str.CompareTo("") == 0)) return 0;\r
       return strings.Add(str,false);\r
     }\r
 \r
     internal uint AddToGUIDHeap(Guid guidNum) {\r
-      return guid.Add(guidNum);\r
+      return guid.Add(guidNum, false);\r
     }\r
 \r
     internal uint AddToBlobHeap(byte[] blobBytes) {\r
       if (blobBytes == null) return 0;\r
-      return blob.Add(blobBytes);\r
+      return blob.Add(blobBytes, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(byte val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(sbyte val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(ushort val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(short val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(uint val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(int val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(ulong val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(long val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(float val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(double val) {\r
-      return blob.Add(val);\r
+      return blob.Add(val, true);\r
     }\r
 \r
     internal uint AddToBlobHeap(string val) {\r
       return blob.Add(val,true);\r
     }\r
 \r
-\r
+                internal void AddCustomAttribute (CustomAttribute cattr)
+                {
+                        if (cattr_list == null)
+                                cattr_list = new ArrayList ();
+                        cattr_list.Add (cattr);
+                }
+
     private ArrayList GetTable(MDTable tableIx) {\r
       int tabIx = (int)tableIx;\r
       if (metaDataTables[tabIx] == null) {\r
@@ -4621,12 +4696,9 @@ if (rsrc != null)
         sizeOfHeaders += streams[i].headerSize();\r
       }\r
       metaDataSize = MetaDataHeaderSize + sizeOfHeaders;\r
-      // Console.WriteLine("Size of meta data headers (tildeStart) = " + metaDataSize);\r
       tildeStart = metaDataSize;\r
       metaDataSize += tildeTide + tildePadding;\r
-      //Console.WriteLine(tildeName + " - size = " + (tildeTide + tildePadding));\r
       for (int i=1; i < numStreams; i++) {\r
-        // Console.WriteLine("Stream " + i + " starts at " + metaDataSize);\r
         streams[i].Start = metaDataSize;\r
         metaDataSize += streams[i].Size();\r
         streams[i].WriteDetails();\r
@@ -4695,7 +4767,12 @@ if (rsrc != null)
       BuildTable(metaDataTables[(int)MDTable.GenericParam]);\r
       BuildTable(metaDataTables[(int)MDTable.MethodSpec]);\r
       BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);\r
-      BuildTable(metaDataTables[(int)MDTable.CustomAttribute]);\r
+
+      if (cattr_list != null) {
+              foreach (CustomAttribute cattr in cattr_list)
+                      cattr.BuildTables (this);
+      }
+
 /*      for (int i=0; i < metaDataTables.Length; i++) {\r
         ArrayList table = metaDataTables[i];\r
         if (table != null) {\r
@@ -4705,6 +4782,7 @@ if (rsrc != null)
         }\r
       }\r
       */\r
+
                         SetIndexSizes();\r
                         for (int i=1; i < numStreams; i++) {\r
                                 streams[i].EndStream();\r
@@ -4824,16 +4902,7 @@ if (rsrc != null)
       } \r
 //      customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));\r
     }\r
-\r
-    internal void DoCustomAttributes(MetaData md) {\r
-      if (customAttributes != null) {\r
-        for (int i=0; i < customAttributes.Count; i++) {\r
-          CustomAttribute ca = (CustomAttribute)customAttributes[i];\r
-          ca.BuildTables(md);\r
-        }\r
-      }\r
-    }\r
-\r
+
     internal uint Token() {\r
       return (((uint)tabIx << 24) | row);\r
     }\r
@@ -4864,8 +4933,9 @@ if (rsrc != null)
     bool largeIx = false;\r
     uint sizeOfHeader;\r
     char[] name;\r
-    Hashtable htable = new Hashtable();\r
-\r
+    Hashtable htable = new Hashtable();
+                Hashtable btable = new Hashtable ();
+
     internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream()) {\r
       if (addInitByte) { Write((byte)0); size = 1; }\r
       this.name = name;\r
@@ -4923,9 +4993,26 @@ if (rsrc != null)
         index = (uint)val;\r
       }\r
                         return index;\r
-                }\r
-\r
-                internal uint Add(Guid guid) {\r
+                }
+                internal uint Add (byte[] str, bool prependSize) {
+                        Object val = btable [str];
+                        uint index = 0;
+                        if (val == null) {
+                                index = size;
+                                btable [str] = index;
+                                if (prependSize) CompressNum ((uint) str.Length);
+                                Write (str);
+                                size = (uint) Seek (0, SeekOrigin.Current);
+                        } else {
+                                index = (uint) val;
+                        }
+                        return index;
+                }
+
+                    
+                internal uint Add(Guid guid, bool prependSize) {\r
+                        byte [] b = guid.ToByteArray ();
+                        if (prependSize) CompressNum ((uint) b.Length);
                         Write(guid.ToByteArray());\r
                         size =(uint)Seek(0,SeekOrigin.Current);\r
                         return tide++;\r
@@ -4933,77 +5020,87 @@ if (rsrc != null)
 \r
                 internal uint Add(byte[] blob) {\r
                         uint ix = size;\r
-                        CompressNum((uint)blob.Length);\r
+                        CompressNum((uint)blob.Length);
                         Write(blob);\r
                         size = (uint)Seek(0,SeekOrigin.Current);\r
                         return ix;\r
                 }\r
 \r
-    internal uint Add(byte val) {\r
+    internal uint Add(byte val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (1);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(sbyte val) {\r
+    internal uint Add(sbyte val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (1);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(ushort val) {\r
+    internal uint Add(ushort val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (2);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(short val) {\r
+    internal uint Add(short val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (2);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(uint val) {\r
+    internal uint Add(uint val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (4);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(int val) {\r
+    internal uint Add(int val, bool prependSize) {\r
       uint ix = size;\r
-      Write(val);\r
+      if (prependSize) CompressNum (4);
+      Write (val);
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(ulong val) {\r
+    internal uint Add(ulong val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (8);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(long val) {\r
+    internal uint Add(long val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (8);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(float val) {\r
+    internal uint Add(float val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (4);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
     }\r
 \r
-    internal uint Add(double val) {\r
+    internal uint Add(double val, bool prependSize) {\r
       uint ix = size;\r
+      if (prependSize) CompressNum (8);
       Write(val);\r
       size = (uint)Seek(0,SeekOrigin.Current);\r
       return ix;\r
@@ -5269,7 +5366,6 @@ if (rsrc != null)
         varArgSig.BuildTables(md);\r
       }\r
       }\r
-      DoCustomAttributes (md);\r
       // Console.WriteLine("method has " + numPars + " parameters");\r
       done = true;\r
     }\r
@@ -5290,6 +5386,8 @@ if (rsrc != null)
 \r
     internal bool ZeroRva () {
         return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
+                        ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
+                        ((implFlags & (ushort)ImplAttr.InternalCall) != 0) || 
                         (pinvokeImpl != null)); // TODO: Not entirely true but works for now
     }
 
@@ -5434,25 +5532,51 @@ if (rsrc != null)
         /// \r
         public class MethPtrType : Type\r
         {\r
-    // MethPtrType == FNPTR\r
-    Method method;\r
-    uint sigIx = 0;\r
-\r
+                bool varArgMeth;
+                Type retType;
+                Type [] parList;
+                Type [] optParList;
+                CallConv callConv;
+                uint numPars;
+                uint numOptPars;
+                uint sigIx = 0;
+
     /// <summary>\r
     /// Create a new function pointer type\r
     /// </summary>\r
     /// <param name="meth">the function to be referenced</param>\r
-                public MethPtrType(Method meth) : base(0x1B)\r
-                {\r
-      method = meth;\r
-                        tabIx = MDTable.TypeSpec;\r
-                }\r
-\r
-    internal sealed override void TypeSig(MemoryStream str) {\r
-      str.WriteByte(typeIndex);\r
-      method.TypeSig(str);\r
-    }\r
-\r
+    public MethPtrType (CallConv callconv, Type retType, Type[] pars,
+                    bool varArgMeth, Type[] optPars) : base(0x1B) {
+      this.retType = retType;
+      callConv = callconv;
+      parList = pars;
+      this.varArgMeth = varArgMeth;
+      if (parList != null) numPars = (uint)parList.Length;
+      if (varArgMeth) {
+        optParList = optPars;
+        if (optParList != null) numOptPars = (uint)optParList.Length;
+        callConv |= CallConv.Vararg;
+      }
+      tabIx = MDTable.TypeSpec;
+    }
+  
+    internal sealed override void TypeSig(MemoryStream sig) {
+      sig.WriteByte(typeIndex);
+      // Bootlegged from method ref
+      sig.WriteByte((byte)callConv);
+      MetaData.CompressNum (numPars + numOptPars, sig);
+      retType.TypeSig (sig);
+      for (int i=0; i < numPars; i++) {
+              parList[i].TypeSig (sig);
+      }
+      if (varArgMeth) {
+              sig.WriteByte (0x41); // Write the sentinel
+        for (int i=0; i < numOptPars; i++) {
+          optParList[i].TypeSig (sig);
+        }
+      }
+    }
+
     internal sealed override void BuildTables(MetaData md) {\r
       if (done) return;\r
       MemoryStream sig = new MemoryStream();\r
@@ -5506,19 +5630,18 @@ if (rsrc != null)
                         }\r
                         return 0;\r
     }\r
-\r
-        }\r
+  }
   /**************************************************************************/  \r
         /// <summary>\r
         /// Descriptor for another module in THIS assembly\r
         /// </summary>\r
-  public class ModuleRef : ResolutionScope\r
+        public class ModuleRef : ResolutionScope, IExternRef
         {\r
 \r
                 internal ModuleRef(MetaData md, string name) : base(name,md) {\r
       tabIx = MDTable.ModuleRef;\r
-                }\r
-\r
+                }
+
     /// <summary>\r
     /// Add a class to this external module.  This is a class declared in\r
     /// another module of THIS assembly.\r
@@ -5526,7 +5649,7 @@ if (rsrc != null)
     /// <param name="nsName">name space name</param>\r
     /// <param name="name">class name</param>\r
     /// <returns>a descriptor for this class in another module</returns>\r
-    public ClassRef AddClass(string nsName, string name, bool exportClass) {\r
+    public ClassRef AddClass(string nsName, string name) {\r
       ClassRef aClass = new ClassRef(nsName,name,metaData);\r
       metaData.AddToTable(MDTable.TypeRef,aClass);\r
       aClass.SetParent(this);\r
@@ -5944,7 +6067,12 @@ if (rsrc != null)
       fileImage = new FileImage(isDLL,outStream);\r
       InitPEFile(name, MakeFileName(null,name,isDLL), hasAssembly);\r
     }\r
-\r
+
+    public PEFile(string name, string module_name, bool isDLL, bool hasAssembly, Stream outStream) {\r
+      fileImage = new FileImage(isDLL,outStream);\r
+      InitPEFile(name, (module_name == null ? MakeFileName(null,name,isDLL) : module_name), hasAssembly);\r
+    }
+
     private void InitPEFile(string name, string fName, bool hasAssembly) {\r
       metaData = fileImage.GetMetaData();\r
       thisMod = new Module(fName,metaData);\r
@@ -6141,7 +6269,12 @@ if (rsrc != null)
       metaData.AddToTable(MDTable.ManifestResource,mr);\r
       //mr.FixName(metaData);\r
     }\r
-\r
+
+    public void AddCustomAttribute (Method meth, byte [] data, MetaDataElement element)
+    {
+            metaData.AddCustomAttribute (new CustomAttribute (element, meth, data));
+    }
+
     /// <summary>\r
     /// Write out the PEFile (the "bake" function)\r
     /// </summary>\r
@@ -6404,10 +6537,10 @@ if (rsrc != null)
     uint flags = 0, padding = 0;\r
                 uint[] relocs; \r
 \r
-                internal Section(string sName, uint sFlags) {\r
-                        name = sName.ToCharArray();\r
-                        flags = sFlags;\r
-                }\r
+                internal Section(string sName, uint sFlags) {
+                  name = sName.ToCharArray();\r
+                  flags = sFlags;\r
+                }
 \r
                 internal uint Tide() { return tide; }\r
 \r