diff options
author | Jb Evain <jbevain@gmail.com> | 2011-10-27 16:53:07 +0400 |
---|---|---|
committer | Jb Evain <jbevain@gmail.com> | 2011-10-27 16:53:07 +0400 |
commit | 8771de6415d3fa5e34b12fd90519a5405c02e8b2 (patch) | |
tree | 0a1707ab3fc77c49d3f5f6f51628089ccffb1d19 /Mono.Cecil.Cil | |
parent | ecdd7454b53a4d6b57c9eb2a500b91025a63b401 (diff) |
First pass at a branch with reduced memory usage; Keeps an open handle on the file, dispose your modules
Diffstat (limited to 'Mono.Cecil.Cil')
-rw-r--r-- | Mono.Cecil.Cil/CodeReader.cs | 69 | ||||
-rw-r--r-- | Mono.Cecil.Cil/CodeWriter.cs | 2 |
2 files changed, 23 insertions, 48 deletions
diff --git a/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.Cil/CodeReader.cs index 61d04d9..7165ed0 100644 --- a/Mono.Cecil.Cil/CodeReader.cs +++ b/Mono.Cecil.Cil/CodeReader.cs @@ -35,58 +35,38 @@ using RVA = System.UInt32; namespace Mono.Cecil.Cil { - sealed class CodeReader : ByteBuffer { + sealed class CodeReader : BinaryStreamReader { readonly internal MetadataReader reader; int start; - Section code_section; - MethodDefinition method; MethodBody body; int Offset { - get { return base.position - start; } + get { return Position - start; } } - public CodeReader (Section section, MetadataReader reader) - : base (section.Data) + public CodeReader (MethodDefinition method, MetadataReader reader) + : base (reader.image.Stream) { - this.code_section = section; this.reader = reader; + this.reader.context = method; + this.Position = (int) reader.image.ResolveVirtualAddress ((uint) method.RVA); } - public MethodBody ReadMethodBody (MethodDefinition method) + public static MethodBody ReadMethodBody (MethodDefinition method, MetadataReader metadata) { - this.method = method; - this.body = new MethodBody (method); + var reader = new CodeReader (method, metadata); + reader.body = new MethodBody (method); - reader.context = method; + reader.ReadMethodBody (); - ReadMethodBody (); - - return this.body; - } - - public void MoveTo (int rva) - { - if (!IsInSection (rva)) { - code_section = reader.image.GetSectionAtVirtualAddress ((uint) rva); - Reset (code_section.Data); - } - - base.position = rva - (int) code_section.VirtualAddress; - } - - bool IsInSection (int rva) - { - return code_section.VirtualAddress <= rva && rva < code_section.VirtualAddress + code_section.SizeOfRawData; + return reader.body; } void ReadMethodBody () { - MoveTo (method.RVA); - var flags = ReadByte (); switch (flags & 0x3) { case 0x2: // tiny @@ -95,7 +75,7 @@ namespace Mono.Cecil.Cil { ReadCode (); break; case 0x3: // fat - base.position--; + Advance (-1); ReadFatMethod (); break; default: @@ -138,17 +118,17 @@ namespace Mono.Cecil.Cil { void ReadCode () { - start = position; + start = Position; var code_size = body.code_size; - if (code_size < 0 || buffer.Length <= (uint) (code_size + position)) + if (code_size < 0 || Length <= (uint) (code_size + Position)) code_size = 0; var end = start + code_size; var instructions = body.instructions = new InstructionCollection (code_size / 3); - while (position < end) { - var offset = base.position - start; + while (Position < end) { + var offset = Position - start; var opcode = ReadOpCode (); var current = new Instruction (offset, opcode); @@ -323,7 +303,7 @@ namespace Mono.Cecil.Cil { void ReadFatSection () { - position--; + Advance (-1); var count = (ReadInt32 () >> 8) / 24; ReadExceptionHandlers ( @@ -369,6 +349,7 @@ namespace Mono.Cecil.Cil { void Align (int align) { align--; + var position = Position; Advance (((position + align) & ~align) - position); } @@ -384,11 +365,6 @@ namespace Mono.Cecil.Cil { var buffer = new ByteBuffer (); symbols = new MethodSymbols (method.Name); - this.method = method; - reader.context = method; - - MoveTo (method.RVA); - var flags = ReadByte (); MetadataToken local_var_token; @@ -401,8 +377,7 @@ namespace Mono.Cecil.Cil { PatchRawCode (buffer, symbols.code_size, writer); break; case 0x3: // fat - base.position--; - + Advance (-1); PatchRawFatMethod (buffer, symbols, writer, out local_var_token); break; default: @@ -519,9 +494,9 @@ namespace Mono.Cecil.Cil { void PatchRawSection (ByteBuffer buffer, MetadataBuilder metadata) { - var position = base.position; + var position = Position; Align (4); - buffer.WriteBytes (base.position - position); + buffer.WriteBytes (Position - position); const byte fat_format = 0x40; const byte more_sects = 0x80; @@ -552,7 +527,7 @@ namespace Mono.Cecil.Cil { void PatchRawFatSection (ByteBuffer buffer, MetadataBuilder metadata) { - position--; + Advance (-1); var length = ReadInt32 (); buffer.WriteInt32 (length); diff --git a/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.Cil/CodeWriter.cs index 02876aa..6ce8452 100644 --- a/Mono.Cecil.Cil/CodeWriter.cs +++ b/Mono.Cecil.Cil/CodeWriter.cs @@ -93,7 +93,7 @@ namespace Mono.Cecil.Cil { void WriteUnresolvedMethodBody (MethodDefinition method) { - var code_reader = metadata.module.Read (method, (_, reader) => reader.code); + var code_reader = metadata.module.Read (method, (m, reader) => new CodeReader (m, reader)); MethodSymbols symbols; var buffer = code_reader.PatchRawMethodBody (method, this, out symbols); |