diff --git a/Directory.Build.props b/Directory.Build.props
index 8c391994c..893643cc4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -9,6 +9,7 @@
$(MSBuildThisFileDirectory)\cecil.snk
$(DefineConstants);NET_CORE
+ true
true
diff --git a/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.Cil/CodeReader.cs
index ac5b31be0..c9b6c5e3c 100644
--- a/Mono.Cecil.Cil/CodeReader.cs
+++ b/Mono.Cecil.Cil/CodeReader.cs
@@ -131,11 +131,7 @@ void ReadFatMethod ()
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
{
- var position = reader.position;
- var variables = reader.ReadVariables (local_var_token);
- reader.position = position;
-
- return variables;
+ return reader.ReadVariables (local_var_token);
}
void ReadCode ()
diff --git a/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.Metadata/BlobHeap.cs
index 574a130c9..93814624c 100644
--- a/Mono.Cecil.Metadata/BlobHeap.cs
+++ b/Mono.Cecil.Metadata/BlobHeap.cs
@@ -9,36 +9,43 @@
//
using System;
+using System.Runtime.InteropServices;
namespace Mono.Cecil.Metadata {
- sealed class BlobHeap : Heap {
+ sealed unsafe class BlobHeap : Heap {
- public BlobHeap (byte [] data)
- : base (data)
+ public BlobHeap (byte* data, uint size)
+ : base (data, size)
{
}
public byte [] Read (uint index)
{
- if (index == 0 || index > this.data.Length - 1)
+ if (index == 0 || index > this.size - 1)
return Empty.Array;
int position = (int) index;
- int length = (int) data.ReadCompressedUInt32 (ref position);
+ int length = (int) Mixin.ReadCompressedUInt32 (data, ref position);
- if (length > data.Length - position)
+ if (length > size - position)
return Empty.Array;
var buffer = new byte [length];
- Buffer.BlockCopy (data, position, buffer, 0, length);
+ Marshal.Copy ((IntPtr)(data + position), buffer, 0, length);
return buffer;
}
public void GetView (uint signature, out byte [] buffer, out int index, out int length)
{
+ buffer = Read (signature);
+ index = 0;
+ length = buffer.Length;
+
+
+ /*
if (signature == 0 || signature > data.Length - 1) {
buffer = null;
index = length = 0;
@@ -49,6 +56,7 @@ public void GetView (uint signature, out byte [] buffer, out int index, out int
index = (int) signature;
length = (int) buffer.ReadCompressedUInt32 (ref index);
+ */
}
}
}
diff --git a/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.Metadata/GuidHeap.cs
index 76ec9d1d1..e8157a7bd 100644
--- a/Mono.Cecil.Metadata/GuidHeap.cs
+++ b/Mono.Cecil.Metadata/GuidHeap.cs
@@ -9,13 +9,14 @@
//
using System;
+using System.Runtime.InteropServices;
namespace Mono.Cecil.Metadata {
- sealed class GuidHeap : Heap {
+ sealed unsafe class GuidHeap : Heap {
- public GuidHeap (byte [] data)
- : base (data)
+ public GuidHeap (byte* data, uint size)
+ : base (data, size)
{
}
@@ -23,14 +24,16 @@ public Guid Read (uint index)
{
const int guid_size = 16;
- if (index == 0 || ((index - 1) + guid_size) > data.Length)
+ if (index == 0 || ((index - 1) + guid_size) > size)
return new Guid ();
- var buffer = new byte [guid_size];
-
- Buffer.BlockCopy (this.data, (int) ((index - 1) * guid_size), buffer, 0, guid_size);
-
- return new Guid (buffer);
+ if (BitConverter.IsLittleEndian) {
+ return *(Guid*) (data + ((index - 1) * guid_size));
+ } else {
+ var buffer = new byte [guid_size];
+ Marshal.Copy ((IntPtr)(data + ((index - 1) * guid_size)), buffer, 0, guid_size);
+ return new Guid (buffer);
+ }
}
}
}
diff --git a/Mono.Cecil.Metadata/Heap.cs b/Mono.Cecil.Metadata/Heap.cs
index 6874d7963..d650ccc2a 100644
--- a/Mono.Cecil.Metadata/Heap.cs
+++ b/Mono.Cecil.Metadata/Heap.cs
@@ -8,17 +8,23 @@
// Licensed under the MIT/X11 license.
//
+using Mono.Cecil.PE;
+
namespace Mono.Cecil.Metadata {
- abstract class Heap {
+ abstract unsafe class Heap {
public int IndexSize;
- readonly internal byte [] data;
+ readonly internal byte* data;
+ readonly internal uint size;
+
+ public ByteSpan Span => new ByteSpan (data, size);
- protected Heap (byte [] data)
+ protected Heap (byte* data, uint size)
{
this.data = data;
+ this.size = size;
}
}
}
diff --git a/Mono.Cecil.Metadata/PdbHeap.cs b/Mono.Cecil.Metadata/PdbHeap.cs
index 39e275ad9..aa62c6d13 100644
--- a/Mono.Cecil.Metadata/PdbHeap.cs
+++ b/Mono.Cecil.Metadata/PdbHeap.cs
@@ -21,8 +21,8 @@ sealed class PdbHeap : Heap {
public long TypeSystemTables;
public uint [] TypeSystemTableRows;
- public PdbHeap (byte [] data)
- : base (data)
+ public unsafe PdbHeap (byte* data, uint size)
+ : base (data, size)
{
}
diff --git a/Mono.Cecil.Metadata/StringHeap.cs b/Mono.Cecil.Metadata/StringHeap.cs
index 4bde70e23..d3316fd7b 100644
--- a/Mono.Cecil.Metadata/StringHeap.cs
+++ b/Mono.Cecil.Metadata/StringHeap.cs
@@ -11,15 +11,16 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Mono.Cecil.PE;
namespace Mono.Cecil.Metadata {
- class StringHeap : Heap {
+ unsafe class StringHeap : Heap {
readonly Dictionary strings = new Dictionary ();
- public StringHeap (byte [] data)
- : base (data)
+ public StringHeap (byte* data, uint size)
+ : base (data, size)
{
}
@@ -32,7 +33,7 @@ public string Read (uint index)
if (strings.TryGetValue (index, out @string))
return @string;
- if (index > data.Length - 1)
+ if (index > size - 1)
return string.Empty;
@string = ReadStringAt (index);
@@ -54,7 +55,12 @@ protected virtual string ReadStringAt (uint index)
length++;
}
- return Encoding.UTF8.GetString (data, start, length);
+#if NET_CORE
+ return Encoding.UTF8.GetString (this.data + start, length);
+#else
+ var buffer = new PByteBuffer (this.data + start, (uint) length);
+ return Encoding.UTF8.GetString (buffer.ReadBytes (length));
+#endif
}
}
}
diff --git a/Mono.Cecil.Metadata/TableHeap.cs b/Mono.Cecil.Metadata/TableHeap.cs
index dee655a34..ba583be4a 100644
--- a/Mono.Cecil.Metadata/TableHeap.cs
+++ b/Mono.Cecil.Metadata/TableHeap.cs
@@ -80,7 +80,7 @@ public bool IsLarge {
}
}
- sealed class TableHeap : Heap {
+ sealed unsafe class TableHeap : Heap {
public long Valid;
public long Sorted;
@@ -91,8 +91,8 @@ public TableInformation this [Table table] {
get { return Tables [(int) table]; }
}
- public TableHeap (byte [] data)
- : base (data)
+ public TableHeap (byte* data, uint size)
+ : base (data, size)
{
}
diff --git a/Mono.Cecil.Metadata/UserStringHeap.cs b/Mono.Cecil.Metadata/UserStringHeap.cs
index 7b1b42ffa..c81661a33 100644
--- a/Mono.Cecil.Metadata/UserStringHeap.cs
+++ b/Mono.Cecil.Metadata/UserStringHeap.cs
@@ -8,12 +8,14 @@
// Licensed under the MIT/X11 license.
//
+using System;
+
namespace Mono.Cecil.Metadata {
- sealed class UserStringHeap : StringHeap {
+ sealed unsafe class UserStringHeap : StringHeap {
- public UserStringHeap (byte [] data)
- : base (data)
+ public UserStringHeap (byte* data, uint size)
+ : base (data, size)
{
}
@@ -21,10 +23,14 @@ protected override string ReadStringAt (uint index)
{
int start = (int) index;
- uint length = (uint) (data.ReadCompressedUInt32 (ref start) & ~1);
+ uint length = (uint) (Mixin.ReadCompressedUInt32 (data, ref start) & ~1);
if (length < 1)
return string.Empty;
+ if (BitConverter.IsLittleEndian) {
+ return new string ((char*)(data + start), 0, (int)length / 2);
+ }
+
var chars = new char [length / 2];
for (int i = start, j = 0; i < start + length; i += 2)
diff --git a/Mono.Cecil.Metadata/Utilities.cs b/Mono.Cecil.Metadata/Utilities.cs
index e29987251..0f18ac1b5 100644
--- a/Mono.Cecil.Metadata/Utilities.cs
+++ b/Mono.Cecil.Metadata/Utilities.cs
@@ -19,7 +19,7 @@ static partial class Mixin {
public const int TableCount = 58;
public const int CodedIndexCount = 14;
- public static uint ReadCompressedUInt32 (this byte [] data, ref int position)
+ public static unsafe uint ReadCompressedUInt32 (byte* data, ref int position)
{
uint integer;
if ((data [position] & 0x80) == 0) {
diff --git a/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.PE/ByteBuffer.cs
index 9a6567ce1..e3be87c62 100644
--- a/Mono.Cecil.PE/ByteBuffer.cs
+++ b/Mono.Cecil.PE/ByteBuffer.cs
@@ -9,9 +9,173 @@
//
using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace Mono.Cecil.PE {
+ readonly unsafe struct ByteSpan {
+ internal readonly byte* pointer;
+ internal readonly uint length;
+
+ public ByteSpan (byte* pointer, uint length)
+ {
+ this.pointer = pointer;
+ this.length = length;
+ }
+ }
+
+ unsafe ref struct PByteBuffer {
+
+ internal readonly ByteSpan span;
+ internal byte* p;
+ internal readonly byte* e;
+
+ public PByteBuffer (byte* bytes, uint length)
+ : this(new ByteSpan(bytes, length))
+ {
+ }
+
+ public PByteBuffer (ByteSpan span)
+ {
+ this.span = span;
+ this.p = this.span.pointer;
+ this.e = this.p + this.span.length;
+ }
+
+ public int RemainingBytes ()
+ {
+ return (int) (e - p);
+ }
+
+ public bool CanReadMore ()
+ {
+ return p < e;
+ }
+
+ public void Advance (int length)
+ {
+ p += length;
+ }
+
+ public byte PeekByte ()
+ {
+ return p [0];
+ }
+
+ public byte ReadByte ()
+ {
+ var b = p [0];
+ p++;
+ return b;
+ }
+
+ public ushort ReadUInt16 ()
+ {
+ ushort value;
+ if (BitConverter.IsLittleEndian) {
+ value = *(ushort*) p;
+ } else {
+ value = (ushort) (p [0] | (p [1] << 8));
+ }
+
+ p += 2;
+ return value;
+ }
+
+ public short ReadInt16 ()
+ {
+ return (short) ReadUInt16 ();
+ }
+
+ public uint ReadUInt32 ()
+ {
+ uint value;
+ if (BitConverter.IsLittleEndian) {
+ value = *(uint*) p;
+ } else {
+ value = (uint) (p [0] | (p [1] << 8) | (p [2] << 16) | (p [3] << 24));
+ }
+
+ p += 4;
+ return value;
+ }
+
+ public int ReadInt32 ()
+ {
+ return (int) ReadUInt32 ();
+ }
+
+ public ulong ReadUInt64 ()
+ {
+ uint low = ReadUInt32 ();
+ uint high = ReadUInt32 ();
+
+ return (((ulong) high) << 32) | low;
+ }
+
+ public long ReadInt64 ()
+ {
+ return (long) ReadUInt64 ();
+ }
+
+ public uint ReadCompressedUInt32 ()
+ {
+ byte first = ReadByte ();
+ if ((first & 0x80) == 0)
+ return first;
+
+ if ((first & 0x40) == 0)
+ return ((uint) (first & ~0x80) << 8)
+ | ReadByte ();
+
+ return ((uint) (first & ~0xc0) << 24)
+ | (uint) ReadByte () << 16
+ | (uint) ReadByte () << 8
+ | ReadByte ();
+ }
+
+ public int ReadCompressedInt32 ()
+ {
+ var b = p [0];
+ var u = (int) ReadCompressedUInt32 ();
+ var v = u >> 1;
+ if ((u & 1) == 0)
+ return v;
+
+ switch (b & 0xc0)
+ {
+ case 0:
+ case 0x40:
+ return v - 0x40;
+ case 0x80:
+ return v - 0x2000;
+ default:
+ return v - 0x10000000;
+ }
+ }
+
+ public byte [] ReadBytes (int count)
+ {
+ var bytes = new byte [count];
+ Marshal.Copy ((IntPtr)p, bytes, 0, count);
+ p += count;
+ return bytes;
+ }
+
+ public float ReadSingle ()
+ {
+ var u = ReadUInt32 ();
+ return *(float*) &u;
+ }
+
+ public double ReadDouble ()
+ {
+ var u = ReadUInt64 ();
+ return *(double*) &u;
+ }
+ }
+
class ByteBuffer {
internal byte [] buffer;
diff --git a/Mono.Cecil.PE/Image.cs b/Mono.Cecil.PE/Image.cs
index 109206187..038bf56ba 100644
--- a/Mono.Cecil.PE/Image.cs
+++ b/Mono.Cecil.PE/Image.cs
@@ -10,7 +10,7 @@
using System;
using System.IO;
-
+using System.Runtime.InteropServices;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
@@ -19,6 +19,27 @@
namespace Mono.Cecil.PE {
+ readonly unsafe struct NativeMemory : IDisposable
+ {
+ private readonly IntPtr pointer;
+ private readonly int length;
+
+ public byte* Pointer => (byte*)pointer;
+
+ public int Length => length;
+
+ public NativeMemory(int length)
+ {
+ this.pointer = Marshal.AllocHGlobal (length);
+ this.length = length;
+ }
+
+ public void Dispose()
+ {
+ Marshal.FreeHGlobal (pointer);
+ }
+ }
+
sealed class Image : IDisposable {
public Disposable Stream;
@@ -36,7 +57,7 @@ sealed class Image : IDisposable {
public Section [] Sections;
- public Section MetadataSection;
+ public NativeMemory Metadata;
public uint EntryPointToken;
public uint Timestamp;
@@ -164,6 +185,7 @@ public bool HasDebugTables ()
public void Dispose ()
{
+ Metadata.Dispose ();
Stream.Dispose ();
}
}
diff --git a/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.PE/ImageReader.cs
index 9731ba90b..a6f44c5e5 100644
--- a/Mono.Cecil.PE/ImageReader.cs
+++ b/Mono.Cecil.PE/ImageReader.cs
@@ -10,7 +10,7 @@
using System;
using System.IO;
-
+using System.Runtime.InteropServices;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;
@@ -19,15 +19,13 @@
namespace Mono.Cecil.PE {
- sealed class ImageReader : BinaryStreamReader {
+ sealed unsafe class ImageReader : BinaryStreamReader {
readonly Image image;
DataDirectory cli;
DataDirectory metadata;
- uint table_heap_offset;
-
public ImageReader (Disposable stream, string file_name)
: base (stream.value)
{
@@ -199,29 +197,28 @@ void ReadOptionalHeaders (out ushort subsystem, out ushort dll_characteristics)
Advance (8);
}
- string ReadAlignedString (int length)
+ string ReadAlignedString (int length, ref PByteBuffer b)
{
int read = 0;
var buffer = new char [length];
while (read < length) {
- var current = ReadByte ();
+ var current = b.ReadByte ();
if (current == 0)
break;
buffer [read++] = (char) current;
}
- Advance (-1 + ((read + 4) & ~3) - read);
+ b.Advance (-1 + ((read + 4) & ~3) - read);
return new string (buffer, 0, read);
}
- string ReadZeroTerminatedString (int length)
+ string ReadZeroTerminatedString (byte[] bytes)
{
int read = 0;
- var buffer = new char [length];
- var bytes = ReadBytes (length);
- while (read < length) {
+ var buffer = new char [bytes.Length];
+ while (read < bytes.Length) {
var current = bytes [read];
if (current == 0)
break;
@@ -240,7 +237,7 @@ void ReadSections (ushort count)
var section = new Section ();
// Name
- section.Name = ReadZeroTerminatedString (8);
+ section.Name = ReadZeroTerminatedString (ReadBytes (8));
// VirtualSize 4
Advance (4);
@@ -292,33 +289,53 @@ void ReadCLIHeader ()
// ManagedNativeHeader 8
}
+ void CopyTo (ref NativeMemory memory)
+ {
+ var destination = memory.Pointer;
+ var size = memory.Length;
+
+ var buffer = new byte [Math.Min (81920, size)];
+ while (size > 0) {
+ int readSize = Math.Min (size, buffer.Length);
+ int bytesRead = Read (buffer, 0, readSize);
+
+ if (bytesRead <= 0 || bytesRead > readSize) {
+ throw new IOException ();
+ }
+
+ Marshal.Copy (buffer, 0, (IntPtr) destination, bytesRead);
+
+ destination += bytesRead;
+ size -= bytesRead;
+ }
+ }
+
void ReadMetadata ()
{
+ image.Metadata = new NativeMemory((int)metadata.Size);
+
MoveTo (metadata);
+ CopyTo (ref image.Metadata);
+
+ var buffer = new PByteBuffer (image.Metadata.Pointer, (uint) image.Metadata.Length);
- if (ReadUInt32 () != 0x424a5342)
+ if (buffer.ReadUInt32 () != 0x424a5342)
throw new BadImageFormatException ();
// MajorVersion 2
// MinorVersion 2
// Reserved 4
- Advance (8);
+ buffer.Advance (8);
- image.RuntimeVersion = ReadZeroTerminatedString (ReadInt32 ());
+ image.RuntimeVersion = ReadZeroTerminatedString (buffer.ReadBytes (buffer.ReadInt32 ()));
// Flags 2
- Advance (2);
-
- var streams = ReadUInt16 ();
+ buffer.Advance (2);
- var section = image.GetSectionAtVirtualAddress (metadata.VirtualAddress);
- if (section == null)
- throw new BadImageFormatException ();
-
- image.MetadataSection = section;
+ var streams = buffer.ReadUInt16 ();
for (int i = 0; i < streams; i++)
- ReadMetadataStream (section);
+ ReadMetadataStream (ref buffer);
if (image.PdbHeap != null)
ReadPdbHeap ();
@@ -368,73 +385,62 @@ void ReadDebugHeader ()
image.DebugHeader = new ImageDebugHeader (entries);
}
- void ReadMetadataStream (Section section)
+ void ReadMetadataStream (ref PByteBuffer buffer)
{
// Offset 4
- uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start
+ var offset = buffer.ReadUInt32 ();
// Size 4
- uint size = ReadUInt32 ();
+ uint size = buffer.ReadUInt32 ();
- var data = ReadHeapData (offset, size);
+ var data = image.Metadata.Pointer + offset;
- var name = ReadAlignedString (16);
+ var name = ReadAlignedString (16, ref buffer);
switch (name) {
case "#~":
case "#-":
- image.TableHeap = new TableHeap (data);
- table_heap_offset = offset;
+ image.TableHeap = new TableHeap (data, size);
break;
case "#Strings":
- image.StringHeap = new StringHeap (data);
+ image.StringHeap = new StringHeap (data, size);
break;
case "#Blob":
- image.BlobHeap = new BlobHeap (data);
+ image.BlobHeap = new BlobHeap (data, size);
break;
case "#GUID":
- image.GuidHeap = new GuidHeap (data);
+ image.GuidHeap = new GuidHeap (data, size);
break;
case "#US":
- image.UserStringHeap = new UserStringHeap (data);
+ image.UserStringHeap = new UserStringHeap (data, size);
break;
case "#Pdb":
- image.PdbHeap = new PdbHeap (data);
+ image.PdbHeap = new PdbHeap (data, size);
break;
}
}
- byte [] ReadHeapData (uint offset, uint size)
- {
- var position = BaseStream.Position;
- MoveTo (offset + image.MetadataSection.PointerToRawData);
- var data = ReadBytes ((int) size);
- BaseStream.Position = position;
-
- return data;
- }
-
void ReadTableHeap ()
{
var heap = image.TableHeap;
- MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData);
+ var buffer = new PByteBuffer (heap.Span);
// Reserved 4
// MajorVersion 1
// MinorVersion 1
- Advance (6);
+ buffer.Advance (6);
// HeapSizes 1
- var sizes = ReadByte ();
+ var sizes = buffer.ReadByte ();
// Reserved2 1
- Advance (1);
+ buffer.Advance (1);
// Valid 8
- heap.Valid = ReadInt64 ();
+ heap.Valid = buffer.ReadInt64 ();
// Sorted 8
- heap.Sorted = ReadInt64 ();
+ heap.Sorted = buffer.ReadInt64 ();
if (image.PdbHeap != null) {
for (int i = 0; i < Mixin.TableCount; i++) {
@@ -449,14 +455,14 @@ void ReadTableHeap ()
if (!heap.HasTable ((Table) i))
continue;
- heap.Tables [i].Length = ReadUInt32 ();
+ heap.Tables [i].Length = buffer.ReadUInt32 ();
}
SetIndexSize (image.StringHeap, sizes, 0x1);
SetIndexSize (image.GuidHeap, sizes, 0x2);
SetIndexSize (image.BlobHeap, sizes, 0x4);
- ComputeTableInformations ();
+ ComputeTableInformations (ref buffer);
}
static void SetIndexSize (Heap heap, uint sizes, byte flag)
@@ -477,9 +483,9 @@ int GetCodedIndexSize (CodedIndex index)
return image.GetCodedIndexSize (index);
}
- void ComputeTableInformations ()
+ void ComputeTableInformations (ref PByteBuffer buffer)
{
- uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header
+ uint offset = (uint) (buffer.p - image.TableHeap.data);
int stridx_size = image.StringHeap.IndexSize;
int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2;
@@ -740,7 +746,7 @@ void ReadPdbHeap ()
{
var heap = image.PdbHeap;
- var buffer = new ByteBuffer (heap.data);
+ var buffer = new PByteBuffer (heap.Span);
heap.Id = buffer.ReadBytes (20);
heap.EntryPoint = buffer.ReadUInt32 ();
diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs
index b64846368..38ef3bf9c 100644
--- a/Mono.Cecil/AssemblyReader.cs
+++ b/Mono.Cecil/AssemblyReader.cs
@@ -442,7 +442,7 @@ public override void ReadSymbols (ModuleDefinition module)
}
}
- sealed class MetadataReader : ByteBuffer {
+ sealed unsafe class MetadataReader {
readonly internal Image image;
readonly internal ModuleDefinition module;
@@ -454,7 +454,6 @@ sealed class MetadataReader : ByteBuffer {
readonly MetadataReader metadata_reader;
public MetadataReader (ModuleDefinition module)
- : base (module.Image.TableHeap.data)
{
this.image = module.Image;
this.module = module;
@@ -463,7 +462,6 @@ public MetadataReader (ModuleDefinition module)
}
public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader)
- : base (image.TableHeap.data)
{
this.image = image;
this.module = module;
@@ -476,23 +474,23 @@ int GetCodedIndexSize (CodedIndex index)
return image.GetCodedIndexSize (index);
}
- uint ReadByIndexSize (int size)
+ uint ReadByIndexSize (int size, ref PByteBuffer buffer)
{
if (size == 4)
- return ReadUInt32 ();
+ return buffer.ReadUInt32 ();
else
- return ReadUInt16 ();
+ return buffer.ReadUInt16 ();
}
- byte [] ReadBlob ()
+ byte [] ReadBlob (ref PByteBuffer buffer)
{
var blob_heap = image.BlobHeap;
if (blob_heap == null) {
- position += 2;
+ buffer.Advance (2);
return Empty.Array;
}
- return blob_heap.Read (ReadBlobIndex ());
+ return blob_heap.Read (ReadBlobIndex (ref buffer));
}
byte [] ReadBlob (uint signature)
@@ -504,10 +502,10 @@ byte [] ReadBlob (uint signature)
return blob_heap.Read (signature);
}
- uint ReadBlobIndex ()
+ uint ReadBlobIndex (ref PByteBuffer buffer)
{
var blob_heap = image.BlobHeap;
- return ReadByIndexSize (blob_heap != null ? blob_heap.IndexSize : 2);
+ return ReadByIndexSize (blob_heap != null ? blob_heap.IndexSize : 2, ref buffer);
}
void GetBlobView (uint signature, out byte [] blob, out int index, out int count)
@@ -522,78 +520,88 @@ void GetBlobView (uint signature, out byte [] blob, out int index, out int count
blob_heap.GetView (signature, out blob, out index, out count);
}
- string ReadString ()
+ string ReadString (ref PByteBuffer buffer)
{
- return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize));
+ return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize, ref buffer));
}
- uint ReadStringIndex ()
+ uint ReadStringIndex (ref PByteBuffer buffer)
{
- return ReadByIndexSize (image.StringHeap.IndexSize);
+ return ReadByIndexSize (image.StringHeap.IndexSize, ref buffer);
}
- Guid ReadGuid ()
+ Guid ReadGuid (ref PByteBuffer buffer)
{
- return image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize));
+ return image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize, ref buffer));
}
- uint ReadTableIndex (Table table)
+ uint ReadTableIndex (Table table, ref PByteBuffer buffer)
{
- return ReadByIndexSize (image.GetTableIndexSize (table));
+ return ReadByIndexSize (image.GetTableIndexSize (table), ref buffer);
}
- MetadataToken ReadMetadataToken (CodedIndex index)
+ MetadataToken ReadMetadataToken (CodedIndex index, ref PByteBuffer buffer)
{
- return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index)));
+ return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index), ref buffer));
}
- int MoveTo (Table table)
+ int MoveTo (Table table, out PByteBuffer buffer)
{
var info = image.TableHeap [table];
- if (info.Length != 0)
- this.position = (int) info.Offset;
+ if (info.Length != 0) {
+ buffer = new PByteBuffer(image.TableHeap.data + info.Offset, info.RowSize * info.Length);
+ return (int) info.Length;
+ }
- return (int) info.Length;
+ buffer = default;
+ return 0;
}
- bool MoveTo (Table table, uint row)
+ bool MoveTo (Table table, uint row, out PByteBuffer buffer)
{
var info = image.TableHeap [table];
var length = info.Length;
- if (length == 0 || row > length)
+ if (length == 0 || row > length) {
+ buffer = default;
return false;
+ }
+
+ var end = info.Offset + (info.RowSize * info.Length);
+ var start = (info.Offset + (info.RowSize * (row - 1)));
+ var size = end - start;
+
+ buffer = new PByteBuffer (image.TableHeap.data + start, size);
- this.position = (int) (info.Offset + (info.RowSize * (row - 1)));
return true;
}
public AssemblyNameDefinition ReadAssemblyNameDefinition ()
{
- if (MoveTo (Table.Assembly) == 0)
+ if (MoveTo (Table.Assembly, out PByteBuffer buffer) == 0)
return null;
var name = new AssemblyNameDefinition ();
- name.HashAlgorithm = (AssemblyHashAlgorithm) ReadUInt32 ();
+ name.HashAlgorithm = (AssemblyHashAlgorithm) buffer.ReadUInt32 ();
- PopulateVersionAndFlags (name);
+ PopulateVersionAndFlags (name, ref buffer);
- name.PublicKey = ReadBlob ();
+ name.PublicKey = ReadBlob (ref buffer);
- PopulateNameAndCulture (name);
+ PopulateNameAndCulture (name, ref buffer);
return name;
}
public ModuleDefinition Populate (ModuleDefinition module)
{
- if (MoveTo (Table.Module) == 0)
+ if (MoveTo (Table.Module, out PByteBuffer buffer) == 0)
return module;
- Advance (2); // Generation
+ buffer.Advance (2); // Generation
- module.Name = ReadString ();
- module.Mvid = ReadGuid ();
+ module.Name = ReadString (ref buffer);
+ module.Mvid = ReadGuid (ref buffer);
return module;
}
@@ -603,25 +611,25 @@ void InitializeAssemblyReferences ()
if (metadata.AssemblyReferences != null)
return;
- int length = MoveTo (Table.AssemblyRef);
+ int length = MoveTo (Table.AssemblyRef, out PByteBuffer buffer);
var references = metadata.AssemblyReferences = new AssemblyNameReference [length];
for (uint i = 0; i < length; i++) {
var reference = new AssemblyNameReference ();
reference.token = new MetadataToken (TokenType.AssemblyRef, i + 1);
- PopulateVersionAndFlags (reference);
+ PopulateVersionAndFlags (reference, ref buffer);
- var key_or_token = ReadBlob ();
+ var key_or_token = ReadBlob (ref buffer);
if (reference.HasPublicKey)
reference.PublicKey = key_or_token;
else
reference.PublicKeyToken = key_or_token;
- PopulateNameAndCulture (reference);
+ PopulateNameAndCulture (reference, ref buffer);
- reference.Hash = ReadBlob ();
+ reference.Hash = ReadBlob (ref buffer);
references [i] = reference;
}
@@ -652,11 +660,11 @@ public Collection ReadModules ()
var modules = new Collection (1);
modules.Add (this.module);
- int length = MoveTo (Table.File);
+ int length = MoveTo (Table.File, out PByteBuffer buffer);
for (uint i = 1; i <= length; i++) {
- var attributes = (FileAttributes) ReadUInt32 ();
- var name = ReadString ();
- ReadBlobIndex ();
+ var attributes = (FileAttributes) buffer.ReadUInt32 ();
+ var name = ReadString (ref buffer);
+ ReadBlobIndex (ref buffer);
if (attributes != FileAttributes.ContainsMetaData)
continue;
@@ -688,11 +696,11 @@ void InitializeModuleReferences ()
if (metadata.ModuleReferences != null)
return;
- int length = MoveTo (Table.ModuleRef);
+ int length = MoveTo (Table.ModuleRef, out PByteBuffer buffer);
var references = metadata.ModuleReferences = new ModuleReference [length];
for (uint i = 0; i < length; i++) {
- var reference = new ModuleReference (ReadString ());
+ var reference = new ModuleReference (ReadString (ref buffer));
reference.token = new MetadataToken (TokenType.ModuleRef, i + 1);
references [i] = reference;
@@ -708,7 +716,7 @@ public Collection ReadModuleReferences ()
public bool HasFileResource ()
{
- int length = MoveTo (Table.File);
+ int length = MoveTo (Table.File, out PByteBuffer buffer);
if (length == 0)
return false;
@@ -721,14 +729,14 @@ public bool HasFileResource ()
public Collection ReadResources ()
{
- int length = MoveTo (Table.ManifestResource);
+ int length = MoveTo (Table.ManifestResource, out PByteBuffer buffer);
var resources = new Collection (length);
for (int i = 1; i <= length; i++) {
- var offset = ReadUInt32 ();
- var flags = (ManifestResourceAttributes) ReadUInt32 ();
- var name = ReadString ();
- var implementation = ReadMetadataToken (CodedIndex.Implementation);
+ var offset = buffer.ReadUInt32 ();
+ var flags = (ManifestResourceAttributes) buffer.ReadUInt32 ();
+ var name = ReadString (ref buffer);
+ var implementation = ReadMetadataToken (CodedIndex.Implementation, ref buffer);
Resource resource;
@@ -756,17 +764,13 @@ public Collection ReadResources ()
Row ReadFileRecord (uint rid)
{
- var position = this.position;
-
- if (!MoveTo (Table.File, rid))
+ if (!MoveTo (Table.File, rid, out PByteBuffer buffer))
throw new ArgumentException ();
var record = new Row (
- (FileAttributes) ReadUInt32 (),
- ReadString (),
- ReadBlobIndex ());
-
- this.position = position;
+ (FileAttributes) buffer.ReadUInt32 (),
+ ReadString (ref buffer),
+ ReadBlobIndex (ref buffer));
return record;
}
@@ -779,21 +783,21 @@ public byte [] GetManagedResource (uint offset)
}) ?? Empty.Array;
}
- void PopulateVersionAndFlags (AssemblyNameReference name)
+ void PopulateVersionAndFlags (AssemblyNameReference name, ref PByteBuffer buffer)
{
name.Version = new Version (
- ReadUInt16 (),
- ReadUInt16 (),
- ReadUInt16 (),
- ReadUInt16 ());
+ buffer.ReadUInt16 (),
+ buffer.ReadUInt16 (),
+ buffer.ReadUInt16 (),
+ buffer.ReadUInt16 ());
- name.Attributes = (AssemblyAttributes) ReadUInt32 ();
+ name.Attributes = (AssemblyAttributes) buffer.ReadUInt32 ();
}
- void PopulateNameAndCulture (AssemblyNameReference name)
+ void PopulateNameAndCulture (AssemblyNameReference name, ref PByteBuffer buffer)
{
- name.Name = ReadString ();
- name.Culture = ReadString ();
+ name.Name = ReadString (ref buffer);
+ name.Culture = ReadString (ref buffer);
}
public TypeDefinitionCollection ReadTypes ()
@@ -838,7 +842,7 @@ void InitializeTypeDefinitions ()
InitializeFields ();
InitializeMethods ();
- int length = MoveTo (Table.TypeDef);
+ int length = image.GetTableLength (Table.TypeDef);
var types = metadata.Types = new TypeDefinition [length];
for (uint i = 0; i < length; i++) {
@@ -907,7 +911,7 @@ void InitializeNestedTypes ()
if (metadata.NestedTypes != null)
return;
- var length = MoveTo (Table.NestedClass);
+ var length = MoveTo (Table.NestedClass, out PByteBuffer buffer);
metadata.NestedTypes = new Dictionary> (length);
metadata.ReverseNestedTypes = new Dictionary (length);
@@ -916,8 +920,8 @@ void InitializeNestedTypes ()
return;
for (int i = 1; i <= length; i++) {
- var nested = ReadTableIndex (Table.TypeDef);
- var declaring = ReadTableIndex (Table.TypeDef);
+ var nested = ReadTableIndex (Table.TypeDef, ref buffer);
+ var declaring = ReadTableIndex (Table.TypeDef, ref buffer);
AddNestedMapping (declaring, nested);
}
@@ -941,12 +945,12 @@ static Collection AddMapping (Dictionary> (length);
for (uint i = 0; i < length; i++) {
- var packing_size = ReadUInt16 ();
- var class_size = ReadUInt32 ();
+ var packing_size = buffer.ReadUInt16 ();
+ var class_size = buffer.ReadUInt32 ();
- var parent = ReadTableIndex (Table.TypeDef);
+ var parent = ReadTableIndex (Table.TypeDef, ref buffer);
class_layouts.Add (parent, new Row (packing_size, class_size));
}
@@ -1061,9 +1064,6 @@ public TypeDefinition GetTypeDefinition (uint rid)
TypeDefinition ReadTypeDefinition (uint rid)
{
- if (!MoveTo (Table.TypeDef, rid))
- return null;
-
return ReadType (rid);
}
@@ -1110,16 +1110,16 @@ TypeReference GetTypeReference (uint rid)
TypeReference ReadTypeReference (uint rid)
{
- if (!MoveTo (Table.TypeRef, rid))
+ if (!MoveTo (Table.TypeRef, rid, out PByteBuffer buffer))
return null;
TypeReference declaring_type = null;
IMetadataScope scope;
- var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope);
+ var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope, ref buffer);
- var name = ReadString ();
- var @namespace = ReadString ();
+ var name = ReadString (ref buffer);
+ var @namespace = ReadString (ref buffer);
var type = new TypeReference (
@namespace,
@@ -1197,20 +1197,28 @@ public IEnumerable GetTypeReferences ()
TypeReference GetTypeSpecification (uint rid)
{
- if (!MoveTo (Table.TypeSpec, rid))
+ if (!MoveTo (Table.TypeSpec, rid, out PByteBuffer buffer))
return null;
- var reader = ReadSignature (ReadBlobIndex ());
- var type = reader.ReadTypeSignature ();
+ var reader = ReadSignature (ReadBlobIndex (ref buffer), out PByteBuffer sig);
+ var type = reader.ReadTypeSignature (ref sig);
if (type.token.RID == 0)
type.token = new MetadataToken (TokenType.TypeSpec, rid);
return type;
}
- SignatureReader ReadSignature (uint signature)
+ SignatureReader ReadSignature (uint signature, out PByteBuffer buffer)
{
- return new SignatureReader (signature, this);
+ var heapSpan = new ByteSpan (image.BlobHeap.data, image.BlobHeap.size);
+ var heapBuffer = new PByteBuffer (heapSpan.pointer, heapSpan.length);
+ heapBuffer.Advance ((int) signature);
+
+ var length = heapBuffer.ReadCompressedUInt32 ();
+
+ buffer = new PByteBuffer (new ByteSpan (heapBuffer.p, length));
+
+ return new SignatureReader (this);
}
public bool HasInterfaces (TypeDefinition type)
@@ -1250,13 +1258,13 @@ void InitializeInterfaces ()
if (metadata.Interfaces != null)
return;
- int length = MoveTo (Table.InterfaceImpl);
+ int length = MoveTo (Table.InterfaceImpl, out PByteBuffer buffer);
metadata.Interfaces = new Dictionary>> (length);
for (uint i = 1; i <= length; i++) {
- var type = ReadTableIndex (Table.TypeDef);
- var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef);
+ var type = ReadTableIndex (Table.TypeDef, ref buffer);
+ var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef, ref buffer);
AddInterfaceMapping (type, new Row (i, @interface));
}
@@ -1276,23 +1284,23 @@ public Collection ReadFields (TypeDefinition type)
var fields = new MemberDefinitionCollection (type, (int) fields_range.Length);
this.context = type;
- if (!MoveTo (Table.FieldPtr, fields_range.Start)) {
- if (!MoveTo (Table.Field, fields_range.Start))
+ if (!MoveTo (Table.FieldPtr, fields_range.Start, out PByteBuffer buffer)) {
+ if (!MoveTo (Table.Field, fields_range.Start, out buffer))
return fields;
for (uint i = 0; i < fields_range.Length; i++)
- ReadField (fields_range.Start + i, fields);
+ ReadField (fields_range.Start + i, fields, ref buffer);
} else
ReadPointers (Table.FieldPtr, Table.Field, fields_range, fields, ReadField);
return fields;
}
- void ReadField (uint field_rid, Collection fields)
+ void ReadField (uint field_rid, Collection fields, ref PByteBuffer buffer)
{
- var attributes = (FieldAttributes) ReadUInt16 ();
- var name = ReadString ();
- var signature = ReadBlobIndex ();
+ var attributes = (FieldAttributes) buffer.ReadUInt16 ();
+ var name = ReadString (ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
var field = new FieldDefinition (name, attributes, ReadFieldType (signature));
field.token = new MetadataToken (TokenType.Field, field_rid);
@@ -1317,14 +1325,14 @@ void InitializeFields ()
TypeReference ReadFieldType (uint signature)
{
- var reader = ReadSignature (signature);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
const byte field_sig = 0x6;
- if (reader.ReadByte () != field_sig)
+ if (sig.ReadByte () != field_sig)
throw new NotSupportedException ();
- return reader.ReadTypeSignature ();
+ return reader.ReadTypeSignature (ref sig);
}
public int ReadFieldRVA (FieldDefinition field)
@@ -1401,13 +1409,13 @@ void InitializeFieldRVAs ()
if (metadata.FieldRVAs != null)
return;
- int length = MoveTo (Table.FieldRVA);
+ int length = MoveTo (Table.FieldRVA, out PByteBuffer buffer);
var field_rvas = metadata.FieldRVAs = new Dictionary (length);
for (int i = 0; i < length; i++) {
- var rva = ReadUInt32 ();
- var field = ReadTableIndex (Table.Field);
+ var rva = buffer.ReadUInt32 ();
+ var field = ReadTableIndex (Table.Field, ref buffer);
field_rvas.Add (field, rva);
}
@@ -1431,13 +1439,13 @@ void InitializeFieldLayouts ()
if (metadata.FieldLayouts != null)
return;
- int length = MoveTo (Table.FieldLayout);
+ int length = MoveTo (Table.FieldLayout, out PByteBuffer buffer);
var field_layouts = metadata.FieldLayouts = new Dictionary (length);
for (int i = 0; i < length; i++) {
- var offset = ReadUInt32 ();
- var field = ReadTableIndex (Table.Field);
+ var offset = buffer.ReadUInt32 ();
+ var field = ReadTableIndex (Table.Field, ref buffer);
field_layouts.Add (field, offset);
}
@@ -1471,23 +1479,23 @@ public Collection ReadEvents (TypeDefinition type)
this.context = type;
- if (!MoveTo (Table.EventPtr, range.Start)) {
- if (!MoveTo (Table.Event, range.Start))
+ if (!MoveTo (Table.EventPtr, range.Start, out PByteBuffer buffer)) {
+ if (!MoveTo (Table.Event, range.Start, out buffer))
return events;
for (uint i = 0; i < range.Length; i++)
- ReadEvent (range.Start + i, events);
+ ReadEvent (range.Start + i, events, ref buffer);
} else
ReadPointers (Table.EventPtr, Table.Event, range, events, ReadEvent);
return events;
}
- void ReadEvent (uint event_rid, Collection events)
+ void ReadEvent (uint event_rid, Collection events, ref PByteBuffer buffer)
{
- var attributes = (EventAttributes) ReadUInt16 ();
- var name = ReadString ();
- var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
+ var attributes = (EventAttributes) buffer.ReadUInt16 ();
+ var name = ReadString (ref buffer);
+ var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef, ref buffer));
var @event = new EventDefinition (name, attributes, event_type);
@event.token = new MetadataToken (TokenType.Event, event_rid);
@@ -1503,13 +1511,13 @@ void InitializeEvents ()
if (metadata.Events != null)
return;
- int length = MoveTo (Table.EventMap);
+ int length = MoveTo (Table.EventMap, out PByteBuffer buffer);
metadata.Events = new Dictionary (length);
for (uint i = 1; i <= length; i++) {
- var type_rid = ReadTableIndex (Table.TypeDef);
- Range events_range = ReadListRange (i, Table.EventMap, Table.Event);
+ var type_rid = ReadTableIndex (Table.TypeDef, ref buffer);
+ Range events_range = ReadListRange (i, Table.EventMap, Table.Event, ref buffer);
metadata.AddEventsRange (type_rid, events_range);
}
}
@@ -1543,36 +1551,37 @@ public Collection ReadProperties (TypeDefinition type)
this.context = type;
- if (!MoveTo (Table.PropertyPtr, range.Start)) {
- if (!MoveTo (Table.Property, range.Start))
+ if (!MoveTo (Table.PropertyPtr, range.Start, out PByteBuffer buffer)) {
+ if (!MoveTo (Table.Property, range.Start, out buffer))
return properties;
for (uint i = 0; i < range.Length; i++)
- ReadProperty (range.Start + i, properties);
+ ReadProperty (range.Start + i, properties, ref buffer);
} else
ReadPointers (Table.PropertyPtr, Table.Property, range, properties, ReadProperty);
return properties;
}
- void ReadProperty (uint property_rid, Collection properties)
+ void ReadProperty (uint property_rid, Collection properties, ref PByteBuffer buffer)
{
- var attributes = (PropertyAttributes) ReadUInt16 ();
- var name = ReadString ();
- var signature = ReadBlobIndex ();
+ var attributes = (PropertyAttributes) buffer.ReadUInt16 ();
+ var name = ReadString (ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
+
+ var reader = ReadSignature (signature, out PByteBuffer sig);
- var reader = ReadSignature (signature);
const byte property_signature = 0x8;
- var calling_convention = reader.ReadByte ();
+ var calling_convention = sig.ReadByte ();
if ((calling_convention & property_signature) == 0)
throw new NotSupportedException ();
var has_this = (calling_convention & 0x20) != 0;
- reader.ReadCompressedUInt32 (); // count
+ sig.ReadCompressedUInt32 (); // count
- var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature ());
+ var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature (ref sig));
property.HasThis = has_this;
property.token = new MetadataToken (TokenType.Property, property_rid);
@@ -1587,13 +1596,13 @@ void InitializeProperties ()
if (metadata.Properties != null)
return;
- int length = MoveTo (Table.PropertyMap);
+ int length = MoveTo (Table.PropertyMap, out PByteBuffer buffer);
metadata.Properties = new Dictionary (length);
for (uint i = 1; i <= length; i++) {
- var type_rid = ReadTableIndex (Table.TypeDef);
- var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property);
+ var type_rid = ReadTableIndex (Table.TypeDef, ref buffer);
+ var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property, ref buffer);
metadata.AddPropertiesRange (type_rid, properties_range);
}
}
@@ -1687,14 +1696,14 @@ void InitializeMethodSemantics ()
if (metadata.Semantics != null)
return;
- int length = MoveTo (Table.MethodSemantics);
+ int length = MoveTo (Table.MethodSemantics, out PByteBuffer buffer);
var semantics = metadata.Semantics = new Dictionary> (0);
for (uint i = 0; i < length; i++) {
- var attributes = (MethodSemanticsAttributes) ReadUInt16 ();
- var method_rid = ReadTableIndex (Table.Method);
- var association = ReadMetadataToken (CodedIndex.HasSemantics);
+ var attributes = (MethodSemanticsAttributes) buffer.ReadUInt16 ();
+ var method_rid = ReadTableIndex (Table.Method, ref buffer);
+ var association = ReadMetadataToken (CodedIndex.HasSemantics, ref buffer);
semantics [method_rid] = new Row (attributes, association);
}
@@ -1735,28 +1744,30 @@ public Collection ReadMethods (TypeDefinition type)
return new MemberDefinitionCollection (type);
var methods = new MemberDefinitionCollection (type, (int) methods_range.Length);
- if (!MoveTo (Table.MethodPtr, methods_range.Start)) {
- if (!MoveTo (Table.Method, methods_range.Start))
+ if (!MoveTo (Table.MethodPtr, methods_range.Start, out PByteBuffer buffer)) {
+ if (!MoveTo (Table.Method, methods_range.Start, out buffer))
return methods;
for (uint i = 0; i < methods_range.Length; i++)
- ReadMethod (methods_range.Start + i, methods);
+ ReadMethod (methods_range.Start + i, methods, ref buffer);
} else
ReadPointers (Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod);
return methods;
}
- void ReadPointers (Table ptr, Table table, Range range, Collection members, Action> reader)
+ delegate void PointerReader (uint rid, Collection members, ref PByteBuffer buffer) where TMember : IMemberDefinition;
+
+ void ReadPointers (Table ptr, Table table, Range range, Collection members, PointerReader reader)
where TMember : IMemberDefinition
{
for (uint i = 0; i < range.Length; i++) {
- MoveTo (ptr, range.Start + i);
+ MoveTo (ptr, range.Start + i, out PByteBuffer buffer);
- var rid = ReadTableIndex (table);
- MoveTo (table, rid);
+ var rid = ReadTableIndex (table, ref buffer);
+ MoveTo (table, rid, out buffer);
- reader (rid, members);
+ reader (rid, members, ref buffer);
}
}
@@ -1773,13 +1784,13 @@ void InitializeMethods ()
metadata.Methods = new MethodDefinition [image.GetTableLength (Table.Method)];
}
- void ReadMethod (uint method_rid, Collection methods)
+ void ReadMethod (uint method_rid, Collection methods, ref PByteBuffer buffer)
{
var method = new MethodDefinition ();
- method.rva = ReadUInt32 ();
- method.ImplAttributes = (MethodImplAttributes) ReadUInt16 ();
- method.Attributes = (MethodAttributes) ReadUInt16 ();
- method.Name = ReadString ();
+ method.rva = buffer.ReadUInt32 ();
+ method.ImplAttributes = (MethodImplAttributes) buffer.ReadUInt16 ();
+ method.Attributes = (MethodAttributes) buffer.ReadUInt16 ();
+ method.Name = ReadString (ref buffer);
method.token = new MetadataToken (TokenType.Method, method_rid);
if (IsDeleted (method))
@@ -1787,8 +1798,8 @@ void ReadMethod (uint method_rid, Collection methods)
methods.Add (method); // attach method
- var signature = ReadBlobIndex ();
- var param_range = ReadListRange (method_rid, Table.Method, Table.Param);
+ var signature = ReadBlobIndex (ref buffer);
+ var param_range = ReadListRange (method_rid, Table.Method, Table.Param, ref buffer);
this.context = method;
@@ -1796,9 +1807,7 @@ void ReadMethod (uint method_rid, Collection methods)
metadata.AddMethodDefinition (method);
if (param_range.Length != 0) {
- var position = base.position;
ReadParameters (method, param_range);
- base.position = position;
}
if (module.IsWindowsMetadata ())
@@ -1807,12 +1816,12 @@ void ReadMethod (uint method_rid, Collection methods)
void ReadParameters (MethodDefinition method, Range param_range)
{
- if (!MoveTo (Table.ParamPtr, param_range.Start)) {
- if (!MoveTo (Table.Param, param_range.Start))
+ if (!MoveTo (Table.ParamPtr, param_range.Start, out PByteBuffer buffer)) {
+ if (!MoveTo (Table.Param, param_range.Start, out buffer))
return;
for (uint i = 0; i < param_range.Length; i++)
- ReadParameter (param_range.Start + i, method);
+ ReadParameter (param_range.Start + i, method, ref buffer);
} else
ReadParameterPointers (method, param_range);
}
@@ -1820,21 +1829,21 @@ void ReadParameters (MethodDefinition method, Range param_range)
void ReadParameterPointers (MethodDefinition method, Range range)
{
for (uint i = 0; i < range.Length; i++) {
- MoveTo (Table.ParamPtr, range.Start + i);
+ MoveTo (Table.ParamPtr, range.Start + i, out PByteBuffer buffer);
- var rid = ReadTableIndex (Table.Param);
+ var rid = ReadTableIndex (Table.Param, ref buffer);
- MoveTo (Table.Param, rid);
+ MoveTo (Table.Param, rid, out buffer);
- ReadParameter (rid, method);
+ ReadParameter (rid, method, ref buffer);
}
}
- void ReadParameter (uint param_rid, MethodDefinition method)
+ void ReadParameter (uint param_rid, MethodDefinition method, ref PByteBuffer buffer)
{
- var attributes = (ParameterAttributes) ReadUInt16 ();
- var sequence = ReadUInt16 ();
- var name = ReadString ();
+ var attributes = (ParameterAttributes) buffer.ReadUInt16 ();
+ var sequence = buffer.ReadUInt16 ();
+ var name = ReadString (ref buffer);
var parameter = sequence == 0
? method.MethodReturnType.Parameter
@@ -1847,8 +1856,8 @@ void ReadParameter (uint param_rid, MethodDefinition method)
void ReadMethodSignature (uint signature, IMethodSignature method)
{
- var reader = ReadSignature (signature);
- reader.ReadMethodSignature (method);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
+ reader.ReadMethodSignature (method, ref sig);
}
public PInvokeInfo ReadPInvokeInfo (MethodDefinition method)
@@ -1874,15 +1883,15 @@ void InitializePInvokes ()
if (metadata.PInvokes != null)
return;
- int length = MoveTo (Table.ImplMap);
+ int length = MoveTo (Table.ImplMap, out PByteBuffer buffer);
var pinvokes = metadata.PInvokes = new Dictionary> (length);
for (int i = 1; i <= length; i++) {
- var attributes = (PInvokeAttributes) ReadUInt16 ();
- var method = ReadMetadataToken (CodedIndex.MemberForwarded);
- var name = ReadStringIndex ();
- var scope = ReadTableIndex (Table.File);
+ var attributes = (PInvokeAttributes) buffer.ReadUInt16 ();
+ var method = ReadMetadataToken (CodedIndex.MemberForwarded, ref buffer);
+ var name = ReadStringIndex (ref buffer);
+ var scope = ReadTableIndex (Table.File, ref buffer);
if (method.TokenType != TokenType.Method)
continue;
@@ -1922,14 +1931,14 @@ public Collection ReadGenericParameters (IGenericParameterProv
void ReadGenericParametersRange (Range range, IGenericParameterProvider provider, GenericParameterCollection generic_parameters)
{
- if (!MoveTo (Table.GenericParam, range.Start))
+ if (!MoveTo (Table.GenericParam, range.Start, out PByteBuffer buffer))
return;
for (uint i = 0; i < range.Length; i++) {
- ReadUInt16 (); // index
- var flags = (GenericParameterAttributes) ReadUInt16 ();
- ReadMetadataToken (CodedIndex.TypeOrMethodDef);
- var name = ReadString ();
+ buffer.ReadUInt16 (); // index
+ var flags = (GenericParameterAttributes) buffer.ReadUInt16 ();
+ ReadMetadataToken (CodedIndex.TypeOrMethodDef, ref buffer);
+ var name = ReadString (ref buffer);
var parameter = new GenericParameter (name, provider);
parameter.token = new MetadataToken (TokenType.GenericParam, range.Start + i);
@@ -1945,17 +1954,19 @@ void InitializeGenericParameters ()
return;
metadata.GenericParameters = InitializeRanges (
- Table.GenericParam, () => {
- Advance (4);
- var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef);
- ReadStringIndex ();
+ Table.GenericParam, (ref PByteBuffer buffer) => {
+ buffer.Advance (4);
+ var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef, ref buffer);
+ ReadStringIndex (ref buffer);
return next;
});
}
- Dictionary InitializeRanges (Table table, Func get_next)
+ delegate MetadataToken NextInRangeReader (ref PByteBuffer buffer);
+
+ Dictionary InitializeRanges (Table table, NextInRangeReader get_next)
{
- int length = MoveTo (table);
+ int length = MoveTo (table, out PByteBuffer buffer);
var ranges = new Dictionary (length);
if (length == 0)
@@ -1965,7 +1976,7 @@ Dictionary InitializeRanges (Table table, Func>> (length);
for (uint i = 1; i <= length; i++) {
AddGenericConstraintMapping (
- ReadTableIndex (Table.GenericParam),
- new Row (i, ReadMetadataToken (CodedIndex.TypeDefOrRef)));
+ ReadTableIndex (Table.GenericParam, ref buffer),
+ new Row (i, ReadMetadataToken (CodedIndex.TypeDefOrRef, ref buffer)));
}
}
@@ -2091,18 +2102,18 @@ void InitializeOverrides ()
if (metadata.Overrides != null)
return;
- var length = MoveTo (Table.MethodImpl);
+ var length = MoveTo (Table.MethodImpl, out PByteBuffer buffer);
metadata.Overrides = new Dictionary> (length);
for (int i = 1; i <= length; i++) {
- ReadTableIndex (Table.TypeDef);
+ ReadTableIndex (Table.TypeDef, ref buffer);
- var method = ReadMetadataToken (CodedIndex.MethodDefOrRef);
+ var method = ReadMetadataToken (CodedIndex.MethodDefOrRef, ref buffer);
if (method.TokenType != TokenType.Method)
throw new NotSupportedException ();
- var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef);
+ var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef, ref buffer);
AddOverrideMapping (method.RID, @override);
}
@@ -2127,10 +2138,10 @@ public int ReadCodeSize (MethodDefinition method)
public CallSite ReadCallSite (MetadataToken token)
{
- if (!MoveTo (Table.StandAloneSig, token.RID))
+ if (!MoveTo (Table.StandAloneSig, token.RID, out PByteBuffer buffer))
return null;
- var signature = ReadBlobIndex ();
+ var signature = ReadBlobIndex (ref buffer);
var call_site = new CallSite ();
@@ -2143,23 +2154,24 @@ public CallSite ReadCallSite (MetadataToken token)
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
{
- if (!MoveTo (Table.StandAloneSig, local_var_token.RID))
+ if (!MoveTo (Table.StandAloneSig, local_var_token.RID, out PByteBuffer buffer))
return null;
- var reader = ReadSignature (ReadBlobIndex ());
+ var reader = ReadSignature (ReadBlobIndex (ref buffer), out PByteBuffer sig);
+
const byte local_sig = 0x7;
- if (reader.ReadByte () != local_sig)
+ if (sig.ReadByte () != local_sig)
throw new NotSupportedException ();
- var count = reader.ReadCompressedUInt32 ();
+ var count = sig.ReadCompressedUInt32 ();
if (count == 0)
return null;
var variables = new VariableDefinitionCollection ((int) count);
for (int i = 0; i < count; i++)
- variables.Add (new VariableDefinition (reader.ReadTypeSignature ()));
+ variables.Add (new VariableDefinition (reader.ReadTypeSignature (ref sig)));
return variables;
}
@@ -2175,7 +2187,6 @@ public IMetadataTokenProvider LookupToken (MetadataToken token)
return metadata_reader.LookupToken (token);
IMetadataTokenProvider element;
- var position = this.position;
var context = this.context;
switch (token.TokenType) {
@@ -2204,7 +2215,6 @@ public IMetadataTokenProvider LookupToken (MetadataToken token)
return null;
}
- this.position = position;
this.context = context;
return element;
@@ -2256,12 +2266,12 @@ MethodDefinition LookupMethod (uint rid)
MethodSpecification GetMethodSpecification (uint rid)
{
- if (!MoveTo (Table.MethodSpec, rid))
+ if (!MoveTo (Table.MethodSpec, rid, out PByteBuffer buffer))
return null;
var element_method = (MethodReference) LookupToken (
- ReadMetadataToken (CodedIndex.MethodDefOrRef));
- var signature = ReadBlobIndex ();
+ ReadMetadataToken (CodedIndex.MethodDefOrRef, ref buffer));
+ var signature = ReadBlobIndex (ref buffer);
var method_spec = ReadMethodSpecSignature (signature, element_method);
method_spec.token = new MetadataToken (TokenType.MethodSpec, rid);
@@ -2270,19 +2280,19 @@ MethodSpecification GetMethodSpecification (uint rid)
MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method)
{
- var reader = ReadSignature (signature);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
const byte methodspec_sig = 0x0a;
- var call_conv = reader.ReadByte ();
+ var call_conv = sig.ReadByte ();
if (call_conv != methodspec_sig)
throw new NotSupportedException ();
- var arity = reader.ReadCompressedUInt32 ();
+ var arity = sig.ReadCompressedUInt32 ();
var instance = new GenericInstanceMethod (method, (int) arity);
- reader.ReadGenericInstanceSignature (method, instance, arity);
+ reader.ReadGenericInstanceSignature (method, instance, arity, ref sig);
return instance;
}
@@ -2303,12 +2313,12 @@ MemberReference GetMemberReference (uint rid)
MemberReference ReadMemberReference (uint rid)
{
- if (!MoveTo (Table.MemberRef, rid))
+ if (!MoveTo (Table.MemberRef, rid, out PByteBuffer buffer))
return null;
- var token = ReadMetadataToken (CodedIndex.MemberRefParent);
- var name = ReadString ();
- var signature = ReadBlobIndex ();
+ var token = ReadMetadataToken (CodedIndex.MemberRefParent, ref buffer);
+ var name = ReadString (ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
MemberReference member;
@@ -2348,19 +2358,20 @@ MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint s
MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type)
{
- var reader = ReadSignature (signature);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
+
const byte field_sig = 0x6;
- if (reader.buffer [reader.position] == field_sig) {
- reader.position++;
+ if (sig.PeekByte () == field_sig) {
+ sig.Advance (1);
var field = new FieldReference ();
field.DeclaringType = declaring_type;
- field.FieldType = reader.ReadTypeSignature ();
+ field.FieldType = reader.ReadTypeSignature (ref sig);
return field;
} else {
var method = new MethodReference ();
method.DeclaringType = declaring_type;
- reader.ReadMethodSignature (method);
+ reader.ReadMethodSignature (method, ref sig);
return method;
}
}
@@ -2411,14 +2422,14 @@ void InitializeConstants ()
if (metadata.Constants != null)
return;
- var length = MoveTo (Table.Constant);
+ var length = MoveTo (Table.Constant, out PByteBuffer buffer);
var constants = metadata.Constants = new Dictionary> (length);
for (uint i = 1; i <= length; i++) {
- var type = (ElementType) ReadUInt16 ();
- var owner = ReadMetadataToken (CodedIndex.HasConstant);
- var signature = ReadBlobIndex ();
+ var type = (ElementType) buffer.ReadUInt16 ();
+ var owner = ReadMetadataToken (CodedIndex.HasConstant, ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
constants.Add (owner, new Row (type, signature));
}
@@ -2432,10 +2443,10 @@ public TypeReference ReadConstantSignature (MetadataToken token)
if (token.RID == 0)
return null;
- if (!MoveTo (Table.StandAloneSig, token.RID))
+ if (!MoveTo (Table.StandAloneSig, token.RID, out PByteBuffer buffer))
return null;
- return ReadFieldType (ReadBlobIndex ());
+ return ReadFieldType (ReadBlobIndex (ref buffer));
}
public object ReadConstant (IConstantProvider owner)
@@ -2481,8 +2492,8 @@ string ReadConstantString (uint signature)
object ReadConstantPrimitive (ElementType type, uint signature)
{
- var reader = ReadSignature (signature);
- return reader.ReadConstantSignature (type);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
+ return reader.ReadConstantSignature (type, ref sig);
}
internal void InitializeCustomAttributes ()
@@ -2491,10 +2502,10 @@ internal void InitializeCustomAttributes ()
return;
metadata.CustomAttributes = InitializeRanges (
- Table.CustomAttribute, () => {
- var next = ReadMetadataToken (CodedIndex.HasCustomAttribute);
- ReadMetadataToken (CodedIndex.CustomAttributeType);
- ReadBlobIndex ();
+ Table.CustomAttribute, (ref PByteBuffer buffer) => {
+ var next = ReadMetadataToken (CodedIndex.HasCustomAttribute, ref buffer);
+ ReadMetadataToken (CodedIndex.CustomAttributeType, ref buffer);
+ ReadBlobIndex (ref buffer);
return next;
});
}
@@ -2534,16 +2545,16 @@ public Collection ReadCustomAttributes (ICustomAttributeProvide
void ReadCustomAttributeRange (Range range, Collection custom_attributes)
{
- if (!MoveTo (Table.CustomAttribute, range.Start))
+ if (!MoveTo (Table.CustomAttribute, range.Start, out PByteBuffer buffer))
return;
for (var i = 0; i < range.Length; i++) {
- ReadMetadataToken (CodedIndex.HasCustomAttribute);
+ ReadMetadataToken (CodedIndex.HasCustomAttribute, ref buffer);
var constructor = (MethodReference) LookupToken (
- ReadMetadataToken (CodedIndex.CustomAttributeType));
+ ReadMetadataToken (CodedIndex.CustomAttributeType, ref buffer));
- var signature = ReadBlobIndex ();
+ var signature = ReadBlobIndex (ref buffer);
custom_attributes.Add (new CustomAttribute (signature, constructor));
}
@@ -2576,27 +2587,27 @@ public byte [] ReadCustomAttributeBlob (uint signature)
public void ReadCustomAttributeSignature (CustomAttribute attribute)
{
- var reader = ReadSignature (attribute.signature);
+ var reader = ReadSignature (attribute.signature, out PByteBuffer sig);
- if (!reader.CanReadMore ())
+ if (!sig.CanReadMore ())
return;
- if (reader.ReadUInt16 () != 0x0001)
+ if (sig.ReadUInt16 () != 0x0001)
throw new InvalidOperationException ();
var constructor = attribute.Constructor;
if (constructor.HasParameters)
- reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters);
+ reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters, ref sig);
- if (!reader.CanReadMore ())
+ if (!sig.CanReadMore ())
return;
- var named = reader.ReadUInt16 ();
+ var named = sig.ReadUInt16 ();
if (named == 0)
return;
- reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties);
+ reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties, ref sig);
}
void InitializeMarshalInfos ()
@@ -2604,13 +2615,13 @@ void InitializeMarshalInfos ()
if (metadata.FieldMarshals != null)
return;
- var length = MoveTo (Table.FieldMarshal);
+ var length = MoveTo (Table.FieldMarshal, out PByteBuffer buffer);
var marshals = metadata.FieldMarshals = new Dictionary (length);
for (int i = 0; i < length; i++) {
- var token = ReadMetadataToken (CodedIndex.HasFieldMarshal);
- var signature = ReadBlobIndex ();
+ var token = ReadMetadataToken (CodedIndex.HasFieldMarshal, ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
if (token.RID == 0)
continue;
@@ -2633,11 +2644,11 @@ public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner)
if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature))
return null;
- var reader = ReadSignature (signature);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
metadata.FieldMarshals.Remove (owner.MetadataToken);
- return reader.ReadMarshalInfo ();
+ return reader.ReadMarshalInfo (ref sig);
}
void InitializeSecurityDeclarations ()
@@ -2646,10 +2657,10 @@ void InitializeSecurityDeclarations ()
return;
metadata.SecurityDeclarations = InitializeRanges (
- Table.DeclSecurity, () => {
- ReadUInt16 ();
- var next = ReadMetadataToken (CodedIndex.HasDeclSecurity);
- ReadBlobIndex ();
+ Table.DeclSecurity, (ref PByteBuffer buffer) => {
+ buffer.ReadUInt16 ();
+ var next = ReadMetadataToken (CodedIndex.HasDeclSecurity, ref buffer);
+ ReadBlobIndex (ref buffer);
return next;
});
}
@@ -2685,13 +2696,13 @@ public Collection ReadSecurityDeclarations (ISecurityDeclar
void ReadSecurityDeclarationRange (Range range, Collection security_declarations)
{
- if (!MoveTo (Table.DeclSecurity, range.Start))
+ if (!MoveTo (Table.DeclSecurity, range.Start, out PByteBuffer buffer))
return;
for (int i = 0; i < range.Length; i++) {
- var action = (SecurityAction) ReadUInt16 ();
- ReadMetadataToken (CodedIndex.HasDeclSecurity);
- var signature = ReadBlobIndex ();
+ var action = (SecurityAction) buffer.ReadUInt16 ();
+ ReadMetadataToken (CodedIndex.HasDeclSecurity, ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
security_declarations.Add (new SecurityDeclaration (action, signature, module));
}
@@ -2705,19 +2716,19 @@ public byte [] ReadSecurityDeclarationBlob (uint signature)
public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration)
{
var signature = declaration.signature;
- var reader = ReadSignature (signature);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
- if (reader.buffer [reader.position] != '.') {
+ if (sig.PeekByte () != '.') {
ReadXmlSecurityDeclaration (signature, declaration);
return;
}
- reader.position++;
- var count = reader.ReadCompressedUInt32 ();
+ sig.Advance (1);
+ var count = sig.ReadCompressedUInt32 ();
var attributes = new Collection ((int) count);
for (int i = 0; i < count; i++)
- attributes.Add (reader.ReadSecurityAttribute ());
+ attributes.Add (reader.ReadSecurityAttribute (ref sig));
declaration.security_attributes = attributes;
}
@@ -2744,18 +2755,18 @@ void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration
public Collection ReadExportedTypes ()
{
- var length = MoveTo (Table.ExportedType);
+ var length = MoveTo (Table.ExportedType, out PByteBuffer buffer);
if (length == 0)
return new Collection ();
var exported_types = new Collection (length);
for (int i = 1; i <= length; i++) {
- var attributes = (TypeAttributes) ReadUInt32 ();
- var identifier = ReadUInt32 ();
- var name = ReadString ();
- var @namespace = ReadString ();
- var implementation = ReadMetadataToken (CodedIndex.Implementation);
+ var attributes = (TypeAttributes) buffer.ReadUInt32 ();
+ var identifier = buffer.ReadUInt32 ();
+ var name = ReadString (ref buffer);
+ var @namespace = ReadString (ref buffer);
+ var implementation = ReadMetadataToken (CodedIndex.Implementation, ref buffer);
ExportedType declaring_type = null;
IMetadataScope scope = null;
@@ -2786,7 +2797,6 @@ public Collection ReadExportedTypes ()
IMetadataScope GetExportedTypeScope (MetadataToken token)
{
- var position = this.position;
IMetadataScope scope;
switch (token.TokenType) {
@@ -2802,17 +2812,16 @@ IMetadataScope GetExportedTypeScope (MetadataToken token)
throw new NotSupportedException ();
}
- this.position = position;
return scope;
}
ModuleReference GetModuleReferenceFromFile (MetadataToken token)
{
- if (!MoveTo (Table.File, token.RID))
+ if (!MoveTo (Table.File, token.RID, out PByteBuffer buffer))
return null;
- ReadUInt32 ();
- var file_name = ReadString ();
+ buffer.Advance (4);
+ var file_name = ReadString (ref buffer);
var modules = module.ModuleReferences;
ModuleReference reference;
@@ -2832,18 +2841,18 @@ void InitializeDocuments ()
if (metadata.Documents != null)
return;
- int length = MoveTo (Table.Document);
+ int length = MoveTo (Table.Document, out PByteBuffer buffer);
var documents = metadata.Documents = new Document [length];
for (uint i = 1; i <= length; i++) {
- var name_index = ReadBlobIndex ();
- var hash_algorithm = ReadGuid ();
- var hash = ReadBlob ();
- var language = ReadGuid ();
+ var name_index = ReadBlobIndex (ref buffer);
+ var hash_algorithm = ReadGuid (ref buffer);
+ var hash = ReadBlob (ref buffer);
+ var language = ReadGuid (ref buffer);
- var signature = ReadSignature (name_index);
- var name = signature.ReadDocumentName ();
+ var signature = ReadSignature (name_index, out PByteBuffer sig);
+ var name = signature.ReadDocumentName (ref sig);
documents [i - 1] = new Document (name) {
HashAlgorithmGuid = hash_algorithm,
@@ -2858,18 +2867,18 @@ public Collection ReadSequencePoints (MethodDefinition method)
{
InitializeDocuments ();
- if (!MoveTo (Table.MethodDebugInformation, method.MetadataToken.RID))
+ if (!MoveTo (Table.MethodDebugInformation, method.MetadataToken.RID, out PByteBuffer buffer))
return new Collection (0);
- var document_index = ReadTableIndex (Table.Document);
- var signature = ReadBlobIndex ();
+ var document_index = ReadTableIndex (Table.Document, ref buffer);
+ var signature = ReadBlobIndex (ref buffer);
if (signature == 0)
return new Collection (0);
var document = GetDocument (document_index);
- var reader = ReadSignature (signature);
+ var reader = ReadSignature (signature, out PByteBuffer sig);
- return reader.ReadSequencePoints (document);
+ return reader.ReadSequencePoints (document, ref sig);
}
public Document GetDocument (uint rid)
@@ -2889,17 +2898,17 @@ void InitializeLocalScopes ()
InitializeMethods ();
- int length = MoveTo (Table.LocalScope);
+ int length = MoveTo (Table.LocalScope, out PByteBuffer buffer);
metadata.LocalScopes = new Dictionary>> ();
for (uint i = 1; i <= length; i++) {
- var method = ReadTableIndex (Table.Method);
- var import = ReadTableIndex (Table.ImportScope);
- var variables = ReadListRange (i, Table.LocalScope, Table.LocalVariable);
- var constants = ReadListRange (i, Table.LocalScope, Table.LocalConstant);
- var scope_start = ReadUInt32 ();
- var scope_length = ReadUInt32 ();
+ var method = ReadTableIndex (Table.Method, ref buffer);
+ var import = ReadTableIndex (Table.ImportScope, ref buffer);
+ var variables = ReadListRange (i, Table.LocalScope, Table.LocalVariable, ref buffer);
+ var constants = ReadListRange (i, Table.LocalScope, Table.LocalConstant, ref buffer);
+ var scope_start = buffer.ReadUInt32 ();
+ var scope_length = buffer.ReadUInt32 ();
metadata.SetLocalScopes (method, AddMapping (metadata.LocalScopes, method, new Row (import, variables, constants, scope_start, scope_length, i)));
}
@@ -2984,12 +2993,12 @@ ScopeDebugInformation ReadLocalScope (Row
VariableDebugInformation ReadLocalVariable (uint rid)
{
- if (!MoveTo (Table.LocalVariable, rid))
+ if (!MoveTo (Table.LocalVariable, rid, out PByteBuffer buffer))
return null;
- var attributes = (VariableAttributes) ReadUInt16 ();
- var index = ReadUInt16 ();
- var name = ReadString ();
+ var attributes = (VariableAttributes) buffer.ReadUInt16 ();
+ var index = buffer.ReadUInt16 ();
+ var name = ReadString (ref buffer);
var variable = new VariableDebugInformation (index, name) { Attributes = attributes, token = new MetadataToken (TokenType.LocalVariable, rid) };
variable.custom_infos = GetCustomDebugInformation (variable);
@@ -2998,29 +3007,29 @@ VariableDebugInformation ReadLocalVariable (uint rid)
ConstantDebugInformation ReadLocalConstant (uint rid)
{
- if (!MoveTo (Table.LocalConstant, rid))
+ if (!MoveTo (Table.LocalConstant, rid, out PByteBuffer buffer))
return null;
- var name = ReadString ();
- var signature = ReadSignature (ReadBlobIndex ());
- var type = signature.ReadTypeSignature ();
+ var name = ReadString (ref buffer);
+ var signature = ReadSignature (ReadBlobIndex (ref buffer), out PByteBuffer sig);
+ var type = signature.ReadTypeSignature (ref sig);
object value;
if (type.etype == ElementType.String) {
- if (signature.buffer [signature.position] != 0xff) {
- var bytes = signature.ReadBytes ((int) (signature.sig_length - (signature.position - signature.start)));
+ if (sig.PeekByte () != 0xff) {
+ var bytes = sig.ReadBytes ((int) (sig.e - sig.p));
value = Encoding.Unicode.GetString (bytes, 0, bytes.Length);
} else
value = null;
} else if (type.IsTypeOf ("System", "Decimal")) {
- var b = signature.ReadByte ();
- value = new decimal (signature.ReadInt32 (), signature.ReadInt32 (), signature.ReadInt32 (), (b & 0x80) != 0, (byte) (b & 0x7f));
+ var bb = sig.ReadByte ();
+ value = new decimal (sig.ReadInt32 (), sig.ReadInt32 (), sig.ReadInt32 (), (bb & 0x80) != 0, (byte) (bb & 0x7f));
} else if (type.IsTypeOf ("System", "DateTime")) {
- value = new DateTime (signature.ReadInt64());
+ value = new DateTime (sig.ReadInt64());
} else if (type.etype == ElementType.Object || type.etype == ElementType.None || type.etype == ElementType.Class) {
value = null;
} else
- value = signature.ReadConstantSignature (type.etype);
+ value = signature.ReadConstantSignature (type.etype, ref sig);
var constant = new ConstantDebugInformation (name, type, value) { token = new MetadataToken (TokenType.LocalConstant, rid) };
constant.custom_infos = GetCustomDebugInformation (constant);
@@ -3032,29 +3041,29 @@ void InitializeImportScopes ()
if (metadata.ImportScopes != null)
return;
- var length = MoveTo (Table.ImportScope);
+ var length = MoveTo (Table.ImportScope, out PByteBuffer buffer);
metadata.ImportScopes = new ImportDebugInformation [length];
for (int i = 1; i <= length; i++) {
- ReadTableIndex (Table.ImportScope);
+ ReadTableIndex (Table.ImportScope, ref buffer);
var import = new ImportDebugInformation ();
import.token = new MetadataToken (TokenType.ImportScope, i);
- var signature = ReadSignature (ReadBlobIndex ());
- while (signature.CanReadMore ())
- import.Targets.Add (ReadImportTarget (signature));
+ var reader = ReadSignature (ReadBlobIndex (ref buffer), out PByteBuffer sig);
+ while (sig.CanReadMore ())
+ import.Targets.Add (ReadImportTarget (reader, ref sig));
metadata.ImportScopes [i - 1] = import;
}
- MoveTo (Table.ImportScope);
+ MoveTo (Table.ImportScope, out buffer);
for (int i = 0; i < length; i++) {
- var parent = ReadTableIndex (Table.ImportScope);
+ var parent = ReadTableIndex (Table.ImportScope, ref buffer);
- ReadBlobIndex ();
+ ReadBlobIndex (ref buffer);
if (parent != 0)
metadata.ImportScopes [i].Parent = metadata.GetImportScope (parent);
@@ -3083,48 +3092,48 @@ string ReadStringBlob (uint signature, Encoding encoding)
return encoding.GetString (blob, index, count);
}
- ImportTarget ReadImportTarget (SignatureReader signature)
+ ImportTarget ReadImportTarget (SignatureReader signature, ref PByteBuffer sig)
{
AssemblyNameReference reference = null;
string @namespace = null;
string alias = null;
TypeReference type = null;
- var kind = (ImportTargetKind) signature.ReadCompressedUInt32 ();
+ var kind = (ImportTargetKind) sig.ReadCompressedUInt32 ();
switch (kind) {
case ImportTargetKind.ImportNamespace:
- @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
+ @namespace = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.ImportNamespaceInAssembly:
- reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ());
- @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
+ reference = metadata.GetAssemblyNameReference (sig.ReadCompressedUInt32 ());
+ @namespace = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.ImportType:
- type = signature.ReadTypeToken ();
+ type = signature.ReadTypeToken (ref sig);
break;
case ImportTargetKind.ImportXmlNamespaceWithAlias:
- alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
- @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
+ alias = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
+ @namespace = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.ImportAlias:
- alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
+ alias = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineAssemblyAlias:
- alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
- reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ());
+ alias = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
+ reference = metadata.GetAssemblyNameReference (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineNamespaceAlias:
- alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
- @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
+ alias = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
+ @namespace = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineNamespaceInAssemblyAlias:
- alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
- reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ());
- @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
+ alias = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
+ reference = metadata.GetAssemblyNameReference (sig.ReadCompressedUInt32 ());
+ @namespace = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
break;
case ImportTargetKind.DefineTypeAlias:
- alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ());
- type = signature.ReadTypeToken ();
+ alias = ReadUTF8StringBlob (sig.ReadCompressedUInt32 ());
+ type = signature.ReadTypeToken (ref sig);
break;
}
@@ -3141,12 +3150,12 @@ void InitializeStateMachineMethods ()
if (metadata.StateMachineMethods != null)
return;
- var length = MoveTo (Table.StateMachineMethod);
+ var length = MoveTo (Table.StateMachineMethod, out PByteBuffer buffer);
metadata.StateMachineMethods = new Dictionary (length);
for (int i = 0; i < length; i++)
- metadata.StateMachineMethods.Add (ReadTableIndex (Table.Method), ReadTableIndex (Table.Method));
+ metadata.StateMachineMethods.Add (ReadTableIndex (Table.Method, ref buffer), ReadTableIndex (Table.Method, ref buffer));
}
public MethodDefinition ReadStateMachineKickoffMethod (MethodDefinition method)
@@ -3165,13 +3174,13 @@ void InitializeCustomDebugInformations ()
if (metadata.CustomDebugInformations != null)
return;
- var length = MoveTo (Table.CustomDebugInformation);
+ var length = MoveTo (Table.CustomDebugInformation, out PByteBuffer buffer);
metadata.CustomDebugInformations = new Dictionary []> ();
for (uint i = 1; i <= length; i++) {
- var token = ReadMetadataToken (CodedIndex.HasCustomDebugInformation);
- var info = new Row (ReadGuid (), ReadBlobIndex (), i);
+ var token = ReadMetadataToken (CodedIndex.HasCustomDebugInformation, ref buffer);
+ var info = new Row (ReadGuid (ref buffer), ReadBlobIndex (ref buffer), i);
Row [] infos;
metadata.CustomDebugInformations.TryGetValue (token, out infos);
@@ -3191,12 +3200,13 @@ public Collection GetCustomDebugInformation (ICustomDebu
for (int i = 0; i < rows.Length; i++) {
if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) {
- var signature = ReadSignature (rows [i].Col2);
+ ReadSignature (rows [i].Col2, out PByteBuffer sig);
+
var scopes = new Collection ();
- while (signature.CanReadMore ()) {
- var start = signature.ReadInt32 ();
- var end = start + signature.ReadInt32 ();
+ while (sig.CanReadMore ()) {
+ var start = sig.ReadInt32 ();
+ var end = start + sig.ReadInt32 ();
scopes.Add (new StateMachineScope (start, end));
}
@@ -3205,17 +3215,17 @@ public Collection GetCustomDebugInformation (ICustomDebu
infos.Add (state_machine);
} else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) {
- var signature = ReadSignature (rows [i].Col2);
+ ReadSignature (rows [i].Col2, out PByteBuffer sig);
- var catch_offset = signature.ReadInt32 () - 1;
+ var catch_offset = sig.ReadInt32 () - 1;
var yields = new Collection ();
var resumes = new Collection ();
var resume_methods = new Collection ();
- while (signature.CanReadMore ()) {
- yields.Add (new InstructionOffset (signature.ReadInt32 ()));
- resumes.Add (new InstructionOffset (signature.ReadInt32 ()));
- resume_methods.Add (GetMethodDefinition (signature.ReadCompressedUInt32 ()));
+ while (sig.CanReadMore ()) {
+ yields.Add (new InstructionOffset (sig.ReadInt32 ()));
+ resumes.Add (new InstructionOffset (sig.ReadInt32 ()));
+ resume_methods.Add (GetMethodDefinition (sig.ReadCompressedUInt32 ()));
}
var async_body = new AsyncMethodBodyDebugInformation (catch_offset);
@@ -3225,16 +3235,17 @@ public Collection GetCustomDebugInformation (ICustomDebu
infos.Add (async_body);
} else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) {
- var signature = ReadSignature (rows [i].Col2);
- var format = signature.ReadInt32 ();
- var length = signature.sig_length - 4;
+ ReadSignature (rows [i].Col2, out PByteBuffer sig);
+
+ var format = sig.ReadInt32 ();
+ var length = sig.span.length - 4;
var info = null as CustomDebugInformation;
if (format == 0) {
- info = new EmbeddedSourceDebugInformation (signature.ReadBytes ((int) length), compress: false);
+ info = new EmbeddedSourceDebugInformation (sig.ReadBytes ((int) length), compress: false);
} else if (format > 0) {
- var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length));
+ var compressed_stream = new MemoryStream (sig.ReadBytes ((int) length));
var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document
var decompressed_stream = new MemoryStream (decompressed_document);
@@ -3260,27 +3271,22 @@ public Collection GetCustomDebugInformation (ICustomDebu
}
}
- sealed class SignatureReader : ByteBuffer {
+ ref struct SignatureReader {
readonly MetadataReader reader;
- readonly internal uint start, sig_length;
TypeSystem TypeSystem {
get { return reader.module.TypeSystem; }
}
- public SignatureReader (uint blob, MetadataReader reader)
- : base (reader.image.BlobHeap.data)
+ public SignatureReader (MetadataReader reader)
{
this.reader = reader;
- this.position = (int) blob;
- this.sig_length = ReadCompressedUInt32();
- this.start = (uint) this.position;
}
- MetadataToken ReadTypeTokenSignature ()
+ MetadataToken ReadTypeTokenSignature (ref PByteBuffer buffer)
{
- return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ());
+ return CodedIndex.TypeDefOrRef.GetMetadataToken (buffer.ReadCompressedUInt32 ());
}
GenericParameter GetGenericParameter (GenericParameterType type, uint var)
@@ -3326,7 +3332,7 @@ static void CheckGenericContext (IGenericParameterProvider owner, int index)
owner_parameters.Add (new GenericParameter (owner));
}
- public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance, uint arity)
+ public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance, uint arity, ref PByteBuffer buffer)
{
if (!provider.IsDefinition)
CheckGenericContext (provider, (int) arity - 1);
@@ -3334,22 +3340,22 @@ public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IG
var instance_arguments = instance.GenericArguments;
for (int i = 0; i < arity; i++)
- instance_arguments.Add (ReadTypeSignature ());
+ instance_arguments.Add (ReadTypeSignature (ref buffer));
}
- ArrayType ReadArrayTypeSignature ()
+ ArrayType ReadArrayTypeSignature (ref PByteBuffer buffer)
{
- var array = new ArrayType (ReadTypeSignature ());
+ var array = new ArrayType (ReadTypeSignature (ref buffer));
- var rank = ReadCompressedUInt32 ();
+ var rank = buffer.ReadCompressedUInt32 ();
- var sizes = new uint [ReadCompressedUInt32 ()];
+ var sizes = new uint [buffer.ReadCompressedUInt32 ()];
for (int i = 0; i < sizes.Length; i++)
- sizes [i] = ReadCompressedUInt32 ();
+ sizes [i] = buffer.ReadCompressedUInt32 ();
- var low_bounds = new int [ReadCompressedUInt32 ()];
+ var low_bounds = new int [buffer.ReadCompressedUInt32 ()];
for (int i = 0; i < low_bounds.Length; i++)
- low_bounds [i] = ReadCompressedInt32 ();
+ low_bounds [i] = buffer.ReadCompressedInt32 ();
array.Dimensions.Clear ();
@@ -3373,61 +3379,61 @@ TypeReference GetTypeDefOrRef (MetadataToken token)
return reader.GetTypeDefOrRef (token);
}
- public TypeReference ReadTypeSignature ()
+ public TypeReference ReadTypeSignature (ref PByteBuffer buffer)
{
- return ReadTypeSignature ((ElementType) ReadByte ());
+ return ReadTypeSignature ((ElementType) buffer.ReadByte (), ref buffer);
}
- public TypeReference ReadTypeToken ()
+ public TypeReference ReadTypeToken (ref PByteBuffer buffer)
{
- return GetTypeDefOrRef (ReadTypeTokenSignature ());
+ return GetTypeDefOrRef (ReadTypeTokenSignature (ref buffer));
}
- TypeReference ReadTypeSignature (ElementType etype)
+ TypeReference ReadTypeSignature (ElementType etype, ref PByteBuffer buffer)
{
switch (etype) {
case ElementType.ValueType: {
- var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
+ var value_type = GetTypeDefOrRef (ReadTypeTokenSignature (ref buffer));
value_type.KnownValueType ();
return value_type;
}
case ElementType.Class:
- return GetTypeDefOrRef (ReadTypeTokenSignature ());
+ return GetTypeDefOrRef (ReadTypeTokenSignature (ref buffer));
case ElementType.Ptr:
- return new PointerType (ReadTypeSignature ());
+ return new PointerType (ReadTypeSignature (ref buffer));
case ElementType.FnPtr: {
var fptr = new FunctionPointerType ();
- ReadMethodSignature (fptr);
+ ReadMethodSignature (fptr, ref buffer);
return fptr;
}
case ElementType.ByRef:
- return new ByReferenceType (ReadTypeSignature ());
+ return new ByReferenceType (ReadTypeSignature (ref buffer));
case ElementType.Pinned:
- return new PinnedType (ReadTypeSignature ());
+ return new PinnedType (ReadTypeSignature (ref buffer));
case ElementType.SzArray:
- return new ArrayType (ReadTypeSignature ());
+ return new ArrayType (ReadTypeSignature (ref buffer));
case ElementType.Array:
- return ReadArrayTypeSignature ();
+ return ReadArrayTypeSignature (ref buffer);
case ElementType.CModOpt:
return new OptionalModifierType (
- GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
+ GetTypeDefOrRef (ReadTypeTokenSignature (ref buffer)), ReadTypeSignature (ref buffer));
case ElementType.CModReqD:
return new RequiredModifierType (
- GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
+ GetTypeDefOrRef (ReadTypeTokenSignature (ref buffer)), ReadTypeSignature (ref buffer));
case ElementType.Sentinel:
- return new SentinelType (ReadTypeSignature ());
+ return new SentinelType (ReadTypeSignature (ref buffer));
case ElementType.Var:
- return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ());
+ return GetGenericParameter (GenericParameterType.Type, buffer.ReadCompressedUInt32 ());
case ElementType.MVar:
- return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ());
+ return GetGenericParameter (GenericParameterType.Method, buffer.ReadCompressedUInt32 ());
case ElementType.GenericInst: {
- var is_value_type = ReadByte () == (byte) ElementType.ValueType;
- var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
+ var is_value_type = buffer.ReadByte () == (byte) ElementType.ValueType;
+ var element_type = GetTypeDefOrRef (ReadTypeTokenSignature (ref buffer));
- var arity = ReadCompressedUInt32 ();
- var generic_instance = new GenericInstanceType (element_type, (int) arity);
+ var arity = buffer.ReadCompressedUInt32 ();
+ var generic_instance = new GenericInstanceType (element_type);
- ReadGenericInstanceSignature (element_type, generic_instance, arity);
+ ReadGenericInstanceSignature (element_type, generic_instance, arity, ref buffer);
if (is_value_type) {
generic_instance.KnownValueType ();
@@ -3445,9 +3451,9 @@ TypeReference ReadTypeSignature (ElementType etype)
}
}
- public void ReadMethodSignature (IMethodSignature method)
+ public void ReadMethodSignature (IMethodSignature method, ref PByteBuffer buffer)
{
- var calling_convention = ReadByte ();
+ var calling_convention = buffer.ReadByte ();
const byte has_this = 0x20;
const byte explicit_this = 0x40;
@@ -3469,15 +3475,15 @@ public void ReadMethodSignature (IMethodSignature method)
reader.context = generic_context;
if ((calling_convention & 0x10) != 0) {
- var arity = ReadCompressedUInt32 ();
+ var arity = buffer.ReadCompressedUInt32 ();
if (generic_context != null && !generic_context.IsDefinition)
CheckGenericContext (generic_context, (int) arity -1 );
}
- var param_count = ReadCompressedUInt32 ();
+ var param_count = buffer.ReadCompressedUInt32 ();
- method.MethodReturnType.ReturnType = ReadTypeSignature ();
+ method.MethodReturnType.ReturnType = ReadTypeSignature (ref buffer);
if (param_count == 0)
return;
@@ -3491,15 +3497,15 @@ public void ReadMethodSignature (IMethodSignature method)
parameters = method.Parameters;
for (int i = 0; i < param_count; i++)
- parameters.Add (new ParameterDefinition (ReadTypeSignature ()));
+ parameters.Add (new ParameterDefinition (ReadTypeSignature (ref buffer)));
}
- public object ReadConstantSignature (ElementType type)
+ public object ReadConstantSignature (ElementType type, ref PByteBuffer buffer)
{
- return ReadPrimitiveValue (type);
+ return ReadPrimitiveValue (type, ref buffer);
}
- public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection parameters)
+ public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection parameters, ref PByteBuffer buffer)
{
var count = parameters.Count;
if (count == 0)
@@ -3509,31 +3515,31 @@ public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute,
for (int i = 0; i < count; i++)
attribute.arguments.Add (
- ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
+ ReadCustomAttributeFixedArgument (parameters [i].ParameterType, ref buffer));
}
- CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)
+ CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type, ref PByteBuffer buffer)
{
if (type.IsArray)
- return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
+ return ReadCustomAttributeFixedArrayArgument ((ArrayType) type, ref buffer);
- return ReadCustomAttributeElement (type);
+ return ReadCustomAttributeElement (type, ref buffer);
}
- public void ReadCustomAttributeNamedArguments (ushort count, ref Collection fields, ref Collection properties)
+ public void ReadCustomAttributeNamedArguments (ushort count, ref Collection fields, ref Collection properties, ref PByteBuffer buffer)
{
for (int i = 0; i < count; i++) {
- if (!CanReadMore ())
+ if (!buffer.CanReadMore ())
return;
- ReadCustomAttributeNamedArgument (ref fields, ref properties);
+ ReadCustomAttributeNamedArgument (ref fields, ref properties, ref buffer);
}
}
- void ReadCustomAttributeNamedArgument (ref Collection fields, ref Collection properties)
+ void ReadCustomAttributeNamedArgument (ref Collection fields, ref Collection properties, ref PByteBuffer buffer)
{
- var kind = ReadByte ();
- var type = ReadCustomAttributeFieldOrPropType ();
- var name = ReadUTF8String ();
+ var kind = buffer.ReadByte ();
+ var type = ReadCustomAttributeFieldOrPropType (ref buffer);
+ var name = ReadUTF8String (ref buffer);
Collection container;
switch (kind) {
@@ -3547,7 +3553,7 @@ void ReadCustomAttributeNamedArgument (ref Collection GetCustomAttributeNamedArgumentCollection (ref Collection collection)
@@ -3558,9 +3564,9 @@ static Collection GetCustomAttributeNamedArgumentC
return collection = new Collection ();
}
- CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type)
+ CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type, ref PByteBuffer buffer)
{
- var length = ReadUInt32 ();
+ var length = buffer.ReadUInt32 ();
if (length == 0xffffffff)
return new CustomAttributeArgument (type, null);
@@ -3572,67 +3578,67 @@ CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type)
var element_type = type.ElementType;
for (int i = 0; i < length; i++)
- arguments [i] = ReadCustomAttributeElement (element_type);
+ arguments [i] = ReadCustomAttributeElement (element_type, ref buffer);
return new CustomAttributeArgument (type, arguments);
}
- CustomAttributeArgument ReadCustomAttributeElement (TypeReference type)
+ CustomAttributeArgument ReadCustomAttributeElement (TypeReference type, ref PByteBuffer buffer)
{
if (type.IsArray)
- return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
+ return ReadCustomAttributeFixedArrayArgument ((ArrayType) type, ref buffer);
return new CustomAttributeArgument (
type,
type.etype == ElementType.Object
- ? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ())
- : ReadCustomAttributeElementValue (type));
+ ? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType (ref buffer), ref buffer)
+ : ReadCustomAttributeElementValue (type, ref buffer));
}
- object ReadCustomAttributeElementValue (TypeReference type)
+ object ReadCustomAttributeElementValue (TypeReference type, ref PByteBuffer buffer)
{
var etype = type.etype;
switch (etype) {
case ElementType.String:
- return ReadUTF8String ();
+ return ReadUTF8String (ref buffer);
case ElementType.None:
if (type.IsTypeOf ("System", "Type"))
- return ReadTypeReference ();
+ return ReadTypeReference (ref buffer);
- return ReadCustomAttributeEnum (type);
+ return ReadCustomAttributeEnum (type, ref buffer);
default:
- return ReadPrimitiveValue (etype);
+ return ReadPrimitiveValue (etype, ref buffer);
}
}
- object ReadPrimitiveValue (ElementType type)
+ object ReadPrimitiveValue (ElementType type, ref PByteBuffer buffer)
{
switch (type) {
case ElementType.Boolean:
- return ReadByte () == 1;
+ return buffer.ReadByte () == 1;
case ElementType.I1:
- return (sbyte) ReadByte ();
+ return (sbyte) buffer.ReadByte ();
case ElementType.U1:
- return ReadByte ();
+ return buffer.ReadByte ();
case ElementType.Char:
- return (char) ReadUInt16 ();
+ return (char) buffer.ReadUInt16 ();
case ElementType.I2:
- return ReadInt16 ();
+ return buffer.ReadInt16 ();
case ElementType.U2:
- return ReadUInt16 ();
+ return buffer.ReadUInt16 ();
case ElementType.I4:
- return ReadInt32 ();
+ return buffer.ReadInt32 ();
case ElementType.U4:
- return ReadUInt32 ();
+ return buffer.ReadUInt32 ();
case ElementType.I8:
- return ReadInt64 ();
+ return buffer.ReadInt64 ();
case ElementType.U8:
- return ReadUInt64 ();
+ return buffer.ReadUInt64 ();
case ElementType.R4:
- return ReadSingle ();
+ return buffer.ReadSingle ();
case ElementType.R8:
- return ReadDouble ();
+ return buffer.ReadDouble ();
default:
throw new NotImplementedException (type.ToString ());
}
@@ -3672,17 +3678,17 @@ TypeReference GetPrimitiveType (ElementType etype)
}
}
- TypeReference ReadCustomAttributeFieldOrPropType ()
+ TypeReference ReadCustomAttributeFieldOrPropType (ref PByteBuffer buffer)
{
- var etype = (ElementType) ReadByte ();
+ var etype = (ElementType) buffer.ReadByte ();
switch (etype) {
case ElementType.Boxed:
return TypeSystem.Object;
case ElementType.SzArray:
- return new ArrayType (ReadCustomAttributeFieldOrPropType ());
+ return new ArrayType (ReadCustomAttributeFieldOrPropType (ref buffer));
case ElementType.Enum:
- return ReadTypeReference ();
+ return ReadTypeReference (ref buffer);
case ElementType.Type:
return TypeSystem.LookupType ("System", "Type");
default:
@@ -3690,77 +3696,78 @@ TypeReference ReadCustomAttributeFieldOrPropType ()
}
}
- public TypeReference ReadTypeReference ()
+ public TypeReference ReadTypeReference (ref PByteBuffer buffer)
{
- return TypeParser.ParseType (reader.module, ReadUTF8String ());
+ return TypeParser.ParseType (reader.module, ReadUTF8String (ref buffer));
}
- object ReadCustomAttributeEnum (TypeReference enum_type)
+ object ReadCustomAttributeEnum (TypeReference enum_type, ref PByteBuffer buffer)
{
var type = enum_type.CheckedResolve ();
if (!type.IsEnum)
throw new ArgumentException ();
- return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ());
+ return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType (), ref buffer);
}
- public SecurityAttribute ReadSecurityAttribute ()
+ public SecurityAttribute ReadSecurityAttribute (ref PByteBuffer buffer)
{
- var attribute = new SecurityAttribute (ReadTypeReference ());
+ var attribute = new SecurityAttribute (ReadTypeReference (ref buffer));
- ReadCompressedUInt32 ();
+ buffer.ReadCompressedUInt32 ();
ReadCustomAttributeNamedArguments (
- (ushort) ReadCompressedUInt32 (),
+ (ushort) buffer.ReadCompressedUInt32 (),
ref attribute.fields,
- ref attribute.properties);
+ ref attribute.properties,
+ ref buffer);
return attribute;
}
- public MarshalInfo ReadMarshalInfo ()
+ public MarshalInfo ReadMarshalInfo (ref PByteBuffer buffer)
{
- var native = ReadNativeType ();
+ var native = ReadNativeType (ref buffer);
switch (native) {
case NativeType.Array: {
var array = new ArrayMarshalInfo ();
- if (CanReadMore ())
- array.element_type = ReadNativeType ();
- if (CanReadMore ())
- array.size_parameter_index = (int) ReadCompressedUInt32 ();
- if (CanReadMore ())
- array.size = (int) ReadCompressedUInt32 ();
- if (CanReadMore ())
- array.size_parameter_multiplier = (int) ReadCompressedUInt32 ();
+ if (buffer.CanReadMore ())
+ array.element_type = ReadNativeType (ref buffer);
+ if (buffer.CanReadMore ())
+ array.size_parameter_index = (int) buffer.ReadCompressedUInt32 ();
+ if (buffer.CanReadMore ())
+ array.size = (int) buffer.ReadCompressedUInt32 ();
+ if (buffer.CanReadMore ())
+ array.size_parameter_multiplier = (int) buffer.ReadCompressedUInt32 ();
return array;
}
case NativeType.SafeArray: {
var array = new SafeArrayMarshalInfo ();
- if (CanReadMore ())
- array.element_type = ReadVariantType ();
+ if (buffer.CanReadMore ())
+ array.element_type = ReadVariantType (ref buffer);
return array;
}
case NativeType.FixedArray: {
var array = new FixedArrayMarshalInfo ();
- if (CanReadMore ())
- array.size = (int) ReadCompressedUInt32 ();
- if (CanReadMore ())
- array.element_type = ReadNativeType ();
+ if (buffer.CanReadMore ())
+ array.size = (int) buffer.ReadCompressedUInt32 ();
+ if (buffer.CanReadMore ())
+ array.element_type = ReadNativeType (ref buffer);
return array;
}
case NativeType.FixedSysString: {
var sys_string = new FixedSysStringMarshalInfo ();
- if (CanReadMore ())
- sys_string.size = (int) ReadCompressedUInt32 ();
+ if (buffer.CanReadMore ())
+ sys_string.size = (int) buffer.ReadCompressedUInt32 ();
return sys_string;
}
case NativeType.CustomMarshaler: {
var marshaler = new CustomMarshalInfo ();
- var guid_value = ReadUTF8String ();
+ var guid_value = ReadUTF8String (ref buffer);
marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty;
- marshaler.unmanaged_type = ReadUTF8String ();
- marshaler.managed_type = ReadTypeReference ();
- marshaler.cookie = ReadUTF8String ();
+ marshaler.unmanaged_type = ReadUTF8String (ref buffer);
+ marshaler.managed_type = ReadTypeReference (ref buffer);
+ marshaler.cookie = ReadUTF8String (ref buffer);
return marshaler;
}
default:
@@ -3768,47 +3775,42 @@ public MarshalInfo ReadMarshalInfo ()
}
}
- NativeType ReadNativeType ()
+ NativeType ReadNativeType (ref PByteBuffer buffer)
{
- return (NativeType) ReadByte ();
+ return (NativeType) buffer.ReadByte ();
}
- VariantType ReadVariantType ()
+ VariantType ReadVariantType (ref PByteBuffer buffer)
{
- return (VariantType) ReadByte ();
+ return (VariantType) buffer.ReadByte ();
}
- string ReadUTF8String ()
+ string ReadUTF8String (ref PByteBuffer buffer)
{
- if (buffer [position] == 0xff) {
- position++;
+ if (buffer.PeekByte () == 0xff) {
+ buffer.Advance (1);
return null;
}
- var length = (int) ReadCompressedUInt32 ();
+ var length = (int) buffer.ReadCompressedUInt32 ();
if (length == 0)
return string.Empty;
- if (position + length > buffer.Length)
- return string.Empty;
-
- var @string = Encoding.UTF8.GetString (buffer, position, length);
+ var bytes = buffer.ReadBytes (length);
- position += length;
- return @string;
+ return Encoding.UTF8.GetString (bytes);
}
- public string ReadDocumentName ()
+ public string ReadDocumentName (ref PByteBuffer buffer)
{
- var separator = (char) buffer [position];
- position++;
+ var separator = (char) buffer.ReadByte ();
var builder = new StringBuilder ();
- for (int i = 0; CanReadMore (); i++) {
+ for (int i = 0; buffer.CanReadMore (); i++) {
if (i > 0 && separator != 0)
builder.Append (separator);
- uint part = ReadCompressedUInt32 ();
+ uint part = buffer.ReadCompressedUInt32 ();
if (part != 0)
builder.Append (reader.ReadUTF8StringBlob (part));
}
@@ -3816,38 +3818,37 @@ public string ReadDocumentName ()
return builder.ToString ();
}
- public Collection ReadSequencePoints (Document document)
+ public Collection ReadSequencePoints (Document document, ref PByteBuffer buffer)
{
- ReadCompressedUInt32 (); // local_sig_token
+ buffer.ReadCompressedUInt32 (); // local_sig_token
if (document == null)
- document = reader.GetDocument (ReadCompressedUInt32 ());
+ document = reader.GetDocument (buffer.ReadCompressedUInt32 ());
var offset = 0;
var start_line = 0;
var start_column = 0;
var first_non_hidden = true;
- //there's about 5 compressed int32's per sequenec points. we don't know exactly how many
+ //there's about 5 compressed int32's per sequence points. we don't know exactly how many
//but let's take a conservative guess so we dont end up reallocating the sequence_points collection
//as it grows.
- var bytes_remaining_for_sequencepoints = sig_length - (position - start);
- var estimated_sequencepoint_amount = (int)bytes_remaining_for_sequencepoints / 5;
+ var estimated_sequencepoint_amount = (int) buffer.RemainingBytes () / 5;
var sequence_points = new Collection (estimated_sequencepoint_amount);
- for (var i = 0; CanReadMore (); i++) {
- var delta_il = (int) ReadCompressedUInt32 ();
+ for (var i = 0; buffer.CanReadMore (); i++) {
+ var delta_il = (int) buffer.ReadCompressedUInt32 ();
if (i > 0 && delta_il == 0) {
- document = reader.GetDocument (ReadCompressedUInt32 ());
+ document = reader.GetDocument (buffer.ReadCompressedUInt32 ());
continue;
}
offset += delta_il;
- var delta_lines = (int) ReadCompressedUInt32 ();
+ var delta_lines = (int) buffer.ReadCompressedUInt32 ();
var delta_columns = delta_lines == 0
- ? (int) ReadCompressedUInt32 ()
- : ReadCompressedInt32 ();
+ ? (int) buffer.ReadCompressedUInt32 ()
+ : buffer.ReadCompressedInt32 ();
if (delta_lines == 0 && delta_columns == 0) {
sequence_points.Add (new SequencePoint (offset, document) {
@@ -3860,11 +3861,11 @@ public Collection ReadSequencePoints (Document document)
}
if (first_non_hidden) {
- start_line = (int) ReadCompressedUInt32 ();
- start_column = (int) ReadCompressedUInt32 ();
+ start_line = (int) buffer.ReadCompressedUInt32 ();
+ start_column = (int) buffer.ReadCompressedUInt32 ();
} else {
- start_line += ReadCompressedInt32 ();
- start_column += ReadCompressedInt32 ();
+ start_line += buffer.ReadCompressedInt32 ();
+ start_column += buffer.ReadCompressedInt32 ();
}
sequence_points.Add (new SequencePoint (offset, document) {
@@ -3878,10 +3879,5 @@ public Collection ReadSequencePoints (Document document)
return sequence_points;
}
-
- public bool CanReadMore ()
- {
- return (position - start) < sig_length;
- }
}
}
diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs
index 3ea1088b3..dc3f0beba 100644
--- a/Mono.Cecil/AssemblyWriter.cs
+++ b/Mono.Cecil/AssemblyWriter.cs
@@ -117,6 +117,7 @@ static void Write (ModuleDefinition module, Disposable stream, WriterPar
using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) {
metadata.SetSymbolWriter (symbol_writer);
BuildMetadata (module, metadata);
+ module.symbol_reader = null;
if (parameters.DeterministicMvid)
metadata.ComputeDeterministicMvid ();
diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs
index 707a1358f..05a6b07b9 100644
--- a/Mono.Cecil/ModuleDefinition.cs
+++ b/Mono.Cecil/ModuleDefinition.cs
@@ -923,12 +923,10 @@ internal object SyncRoot {
internal void Read (TItem item, Action read)
{
lock (module_lock) {
- var position = reader.position;
var context = reader.context;
read (item, reader);
- reader.position = position;
reader.context = context;
}
}
@@ -936,12 +934,10 @@ internal void Read (TItem item, Action read)
internal TRet Read (TItem item, Func read)
{
lock (module_lock) {
- var position = reader.position;
var context = reader.context;
var ret = read (item, reader);
- reader.position = position;
reader.context = context;
return ret;
@@ -954,12 +950,10 @@ internal TRet Read (ref TRet variable, TItem item, Func ();
}
- public byte[] GetDebugInfo (out ImageDebugDirectory idd)
+ public byte [] GetDebugInfo (out ImageDebugDirectory idd)
{
int size;
// get size of debug info
writer.GetDebugInfo (out idd, 0, out size, null);
- byte[] debug_info = new byte[size];
+ byte [] debug_info = new byte [size];
writer.GetDebugInfo (out idd, size, out size, debug_info);
return debug_info;