2
0
Эх сурвалжийг харах

2004-07-30 Martin Baulig <[email protected]>

	The library is now called Mono.CompilerServices.SymbolWriter.dll
	and is in the Mono.CompilerServices.SymbolWriter namespace.

	* MonoSymbolFile.cs (MonoDebuggerSupport.GetGuid): New public
	static method.
	(MonoSymbolFile.WriteString): Use the BinaryWriter's method.
	(MonoSymbolFile.ReadString): Use the BinaryReader's method.
	(MonoSymbolFile.Write): Write the module's Guid into the symbol
	file.

	* MonoSymbolTable.cs, MonoSymbolWriter.cs: Reworked the API.

svn path=/trunk/mcs/; revision=31669
Martin Baulig 21 жил өмнө
parent
commit
082132ef56

+ 14 - 0
mcs/class/Mono.CSharp.Debugger/ChangeLog

@@ -1,3 +1,17 @@
+2004-07-30  Martin Baulig  <[email protected]>
+
+	The library is now called Mono.CompilerServices.SymbolWriter.dll
+	and is in the Mono.CompilerServices.SymbolWriter namespace.
+
+	* MonoSymbolFile.cs (MonoDebuggerSupport.GetGuid): New public
+	static method.
+	(MonoSymbolFile.WriteString): Use the BinaryWriter's method.
+	(MonoSymbolFile.ReadString): Use the BinaryReader's method.
+	(MonoSymbolFile.Write): Write the module's Guid into the symbol
+	file.
+
+	* MonoSymbolTable.cs, MonoSymbolWriter.cs: Reworked the API.
+
 2004-07-27  Martin Baulig  <[email protected]>
 
 	* MonoSymbolFile.cs (MonoSymbolFile.Write): Sort the methods

+ 1 - 1
mcs/class/Mono.CSharp.Debugger/Makefile

@@ -2,7 +2,7 @@ thisdir = class/Mono.CSharp.Debugger
 SUBDIRS =
 include ../../build/rules.make
 
-LIBRARY = Mono.CSharp.Debugger.dll
+LIBRARY = Mono.CompilerServices.SymbolWriter.dll
 LIBRARY_USE_INTERMEDIATE_FILE = yes
 
 LIB_MCS_FLAGS = /r:$(corlib)

+ 0 - 0
mcs/class/Mono.CSharp.Debugger/Mono.CSharp.Debugger.dll.sources → mcs/class/Mono.CSharp.Debugger/Mono.CompilerServices.SymbolWriter.dll.sources


+ 78 - 62
mcs/class/Mono.CSharp.Debugger/MonoSymbolFile.cs

@@ -34,7 +34,7 @@ using System.Collections;
 using System.Text;
 using System.IO;
 	
-namespace Mono.CSharp.Debugger
+namespace Mono.CompilerServices.SymbolWriter
 {
 	public class MonoSymbolFileException : Exception
 	{
@@ -190,22 +190,46 @@ namespace Mono.CSharp.Debugger
 		}
 	}
 
+	internal class MyBinaryWriter : BinaryWriter
+	{
+		public MyBinaryWriter (Stream stream)
+			: base (stream)
+		{ }
+
+		public void WriteLeb128 (int value)
+		{
+			base.Write7BitEncodedInt (value);
+		}
+	}
+
+	internal class MyBinaryReader : BinaryReader
+	{
+		public MyBinaryReader (Stream stream)
+			: base (stream)
+		{ }
+
+		public int ReadLeb128 ()
+		{
+			return base.Read7BitEncodedInt ();
+		}
+	}
+
 	public class MonoDebuggerSupport
 	{
 		static GetTypeFunc get_type;
 		static GetMethodTokenFunc get_method_token;
 		static GetMethodFunc get_method;
 		static GetLocalTypeFromSignatureFunc local_type_from_sig;
+		static GetGuidFunc get_guid;
 
 		delegate Type GetTypeFunc (Assembly assembly, int token);
 		delegate int GetMethodTokenFunc (Assembly assembly, MethodBase method);
 		delegate MethodBase GetMethodFunc (Assembly assembly, int token);
 		delegate Type GetLocalTypeFromSignatureFunc (Assembly assembly, byte[] sig);
+		delegate Guid GetGuidFunc (Module module);
 
-		static Delegate create_delegate (Type delegate_type, string name)
+		static Delegate create_delegate (Type type, Type delegate_type, string name)
 		{
-			Type type = typeof (Assembly);
-
 			MethodInfo mi = type.GetMethod (name, BindingFlags.Static |
 							BindingFlags.NonPublic);
 			if (mi == null)
@@ -217,17 +241,23 @@ namespace Mono.CSharp.Debugger
 		static MonoDebuggerSupport ()
 		{
 			get_type = (GetTypeFunc) create_delegate (
-				typeof (GetTypeFunc), "MonoDebugger_GetType");
+				typeof (Assembly), typeof (GetTypeFunc),
+				"MonoDebugger_GetType");
 
 			get_method_token = (GetMethodTokenFunc) create_delegate (
-				typeof (GetMethodTokenFunc), "MonoDebugger_GetMethodToken");
+				typeof (Assembly), typeof (GetMethodTokenFunc),
+				"MonoDebugger_GetMethodToken");
 
 			get_method = (GetMethodFunc) create_delegate (
-				typeof (GetMethodFunc), "MonoDebugger_GetMethod");
+				typeof (Assembly), typeof (GetMethodFunc),
+				"MonoDebugger_GetMethod");
 
 			local_type_from_sig = (GetLocalTypeFromSignatureFunc) create_delegate (
-				typeof (GetLocalTypeFromSignatureFunc),
+				typeof (Assembly), typeof (GetLocalTypeFromSignatureFunc),
 				"MonoDebugger_GetLocalTypeFromSignature");
+
+			get_guid = (GetGuidFunc) create_delegate (
+				typeof (Module), typeof (GetGuidFunc), "MonoDebugger_GetGuid");
 		}
 
 		public static Type GetType (Assembly assembly, int token)
@@ -249,6 +279,11 @@ namespace Mono.CSharp.Debugger
 		{
 			return local_type_from_sig (assembly, sig);
 		}
+
+		public static Guid GetGuid (Module module)
+		{
+			return get_guid (module);
+		}
 	}
 
 	public class MonoSymbolFile : IDisposable
@@ -264,6 +299,8 @@ namespace Mono.CSharp.Debugger
 		int last_source_index;
 		int last_namespace_index;
 
+		public int NumLineNumbers;
+
 		public MonoSymbolFile ()
 		{ }
 
@@ -307,53 +344,25 @@ namespace Mono.CSharp.Debugger
 		int maxCharsPerRound;
 		static Encoding enc = Encoding.UTF8;
 		
-		internal void WriteString (BinaryWriter bw, string s)
-		{
-			int len = enc.GetByteCount (s);
-			bw.Write (len);
-			StringSize += len;
-			
-			if (stringBuffer == null) {
-				stringBuffer = new byte [512];
-				maxCharsPerRound = 512 / enc.GetMaxByteCount (1);
-			}
-			
-			int chpos = 0;
-			int chrem = s.Length;
-			while (chrem > 0) {
-				int cch = (chrem > maxCharsPerRound) ? maxCharsPerRound : chrem;
-				int blen = enc.GetBytes (s, chpos, cch, stringBuffer, 0);
-				bw.Write (stringBuffer, 0, blen);
-				
-				chpos += cch;
-				chrem -= cch;
-			}
-		}
-
 		internal string ReadString (int offset)
 		{
 			int old_pos = (int) reader.BaseStream.Position;
 			reader.BaseStream.Position = offset;
 
-			string text = ReadString ();
+			string text = reader.ReadString ();
 
 			reader.BaseStream.Position = old_pos;
 			return text;
 		}
 
-		internal string ReadString ()
-		{
-			int length = reader.ReadInt32 ();
-			byte[] data = reader.ReadBytes (length);
-			return Encoding.UTF8.GetString (data);
-		}
-
-		void Write (BinaryWriter bw)
+		void Write (MyBinaryWriter bw, Guid guid)
 		{
 			// Magic number and file version.
 			bw.Write (OffsetTable.Magic);
 			bw.Write (OffsetTable.Version);
 
+			bw.Write (guid.ToByteArray ());
+
 			//
 			// Offsets of file sections; we must write this after we're done
 			// writing the whole file, so we just reserve the space for it here.
@@ -407,62 +416,69 @@ namespace Mono.CSharp.Debugger
 			bw.Seek (0, SeekOrigin.End);
 		}
 
-		public byte[] CreateSymbolFile ()
+		public byte[] CreateSymbolFile (Guid guid)
 		{
 			if (reader != null)
 				throw new InvalidOperationException ();
 
 			using (MyMemoryStream stream = new MyMemoryStream ()) {
-				Write (new BinaryWriter (stream));
+				Write (new MyBinaryWriter (stream), guid);
 				return stream.GetContents ();
 			}
 		}
 
 		Assembly assembly;
-		BinaryReader reader;
+		MyBinaryReader reader;
 		Hashtable method_hash;
 		Hashtable source_file_hash;
 
 		Hashtable method_token_hash;
 		Hashtable source_name_hash;
 
-		protected MonoSymbolFile (Assembly assembly, Stream stream)
+		protected MonoSymbolFile (string filename, Assembly assembly)
 		{
 			this.assembly = assembly;
 
-			reader = new BinaryReader (stream);
+			FileStream stream = new FileStream (filename, FileMode.Open);
+			reader = new MyBinaryReader (stream);
 
 			try {
 				long magic = reader.ReadInt64 ();
 				long version = reader.ReadInt32 ();
-				if ((magic != OffsetTable.Magic) || (version != OffsetTable.Version))
-					throw new MonoSymbolFileException ();
+				if (magic != OffsetTable.Magic)
+					throw new MonoSymbolFileException (
+						"Symbol file `{0}' is not a valid " +
+						"Mono symbol file", filename);
+				if (version != OffsetTable.Version)
+					throw new MonoSymbolFileException (
+						"Symbol file `{0}' has version {1}, " +
+						"but expected {2}", filename, version,
+						OffsetTable.Version);
 				ot = new OffsetTable (reader);
 			} catch {
-				throw new MonoSymbolFileException ();
+				throw new MonoSymbolFileException (
+					"Cannot read symbol file `{0}'", filename);
 			}
 
+			Guid guid = new Guid (reader.ReadBytes (16));
+			Module[] modules = assembly.GetModules ();
+			Guid assembly_guid = MonoDebuggerSupport.GetGuid (modules [0]);
+
+			if (guid != assembly_guid)
+				throw new MonoSymbolFileException (
+					"Symbol file `{0}' does not match assembly `{1}'",
+					filename, assembly.Location);
+
 			method_hash = new Hashtable ();
 			source_file_hash = new Hashtable ();
 		}
 
 		public static MonoSymbolFile ReadSymbolFile (Assembly assembly)
 		{
-			Stream stream = assembly.GetManifestResourceStream ("MonoSymbolFile");
-			if (stream != null)
-				return new MonoSymbolFile (assembly, stream);
-
-			string basename;
 			string filename = assembly.Location;
-			if (filename.EndsWith (".exe") || filename.EndsWith (".dll"))
-				basename = filename.Substring (0, filename.Length - 4);
-			else
-				basename = filename;
-
-			string name = basename + ".mdb";
+			string name = filename + ".mdb";
 
-			stream = new FileStream (name, FileMode.Open);
-			return new MonoSymbolFile (assembly, stream);
+			return new MonoSymbolFile (filename, assembly);
 		}
 
 		public Assembly Assembly {
@@ -633,7 +649,7 @@ namespace Mono.CSharp.Debugger
 			return (int) value;
 		}
 
-		internal BinaryReader BinaryReader {
+		internal MyBinaryReader BinaryReader {
 			get {
 				if (reader == null)
 					throw new InvalidOperationException ();

+ 45 - 86
mcs/class/Mono.CSharp.Debugger/MonoSymbolTable.cs

@@ -29,7 +29,6 @@
 //
 
 using System;
-using System.Reflection;
 using System.Collections;
 using System.Text;
 using System.IO;
@@ -68,11 +67,11 @@ using System.IO;
 // changing the file format.
 //
 
-namespace Mono.CSharp.Debugger
+namespace Mono.CompilerServices.SymbolWriter
 {
 	public struct OffsetTable
 	{
-		public const int  Version = 37;
+		public const int  Version = 38;
 		public const long Magic   = 0x45e82623fd7fa614;
 
 		#region This is actually written to the symbol file
@@ -208,7 +207,7 @@ namespace Mono.CSharp.Debugger
 			this.StartOffset = start_offset;
 		}
 
-		internal LexicalBlockEntry (int index, BinaryReader reader)
+		internal LexicalBlockEntry (int index, MyBinaryReader reader)
 		{
 			this.Index = index;
 			this.StartOffset = reader.ReadInt32 ();
@@ -220,7 +219,7 @@ namespace Mono.CSharp.Debugger
 			this.EndOffset = end_offset;
 		}
 
-		internal void Write (BinaryWriter bw)
+		internal void Write (MyBinaryWriter bw)
 		{
 			bw.Write (StartOffset);
 			bw.Write (EndOffset);
@@ -236,43 +235,36 @@ namespace Mono.CSharp.Debugger
 	{
 		#region This is actually written to the symbol file
 		public readonly string Name;
-		public readonly FieldAttributes Attributes;
 		public readonly byte[] Signature;
 		public readonly int BlockIndex;
 		#endregion
 
-		public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature,
-					   int BlockIndex)
+		public LocalVariableEntry (string Name, byte[] Signature, int BlockIndex)
 		{
 			this.Name = Name;
-			this.Attributes = Attributes;
 			this.Signature = Signature;
 			this.BlockIndex = BlockIndex;
 		}
 
-		internal LocalVariableEntry (BinaryReader reader)
+		internal LocalVariableEntry (MyBinaryReader reader)
 		{
-			int name_length = reader.ReadInt32 ();
-			byte[] name = reader.ReadBytes (name_length);
-			Name = Encoding.UTF8.GetString (name);
-			Attributes = (FieldAttributes) reader.ReadInt32 ();
-			int sig_length = reader.ReadInt32 ();
+			Name = reader.ReadString ();
+			int sig_length = reader.ReadLeb128 ();
 			Signature = reader.ReadBytes (sig_length);
-			BlockIndex = reader.ReadInt32 ();
+			BlockIndex = reader.ReadLeb128 ();
 		}
 
-		internal void Write (MonoSymbolFile file, BinaryWriter bw)
+		internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
 		{
-			file.WriteString (bw, Name);
-			bw.Write ((int) Attributes);
-			bw.Write ((int) Signature.Length);
+			bw.Write (Name);
+			bw.WriteLeb128 ((int) Signature.Length);
 			bw.Write (Signature);
-			bw.Write (BlockIndex);
+			bw.WriteLeb128 (BlockIndex);
 		}
 
 		public override string ToString ()
 		{
-			return String.Format ("[LocalVariable {0}:{1}]", Name, Attributes);
+			return String.Format ("[LocalVariable {0}]", Name);
 		}
 	}
 
@@ -297,7 +289,7 @@ namespace Mono.CSharp.Debugger
 			get { return 24; }
 		}
 
-		protected SourceFileEntry (MonoSymbolFile file, string file_name)
+		public SourceFileEntry (MonoSymbolFile file, string file_name)
 		{
 			this.file = file;
 			this.file_name = file_name;
@@ -308,17 +300,16 @@ namespace Mono.CSharp.Debugger
 			namespaces = new ArrayList ();
 		}
 
-		public void DefineMethod (string name, int token, int num_params,
-					  LocalVariableEntry[] locals, LineNumberEntry[] lines,
-					  LexicalBlockEntry[] blocks, int start, int end,
-					  int namespace_id)
+		public void DefineMethod (string name, int token, LocalVariableEntry[] locals,
+					  LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
+					  int start, int end, int namespace_id)
 		{
 			if (!creating)
 				throw new InvalidOperationException ();
 
 			MethodEntry entry = new MethodEntry (
-				file, this, name, (int) token, num_params,
-				locals, lines, blocks, start, end, namespace_id);
+				file, this, name, (int) token, locals, lines, blocks,
+				start, end, namespace_id);
 
 			methods.Add (entry);
 			file.AddMethod (entry);
@@ -335,10 +326,10 @@ namespace Mono.CSharp.Debugger
 			return index;
 		}
 
-		internal void WriteData (BinaryWriter bw)
+		internal void WriteData (MyBinaryWriter bw)
 		{
 			NameOffset = (int) bw.BaseStream.Position;
-			file.WriteString (bw, file_name);
+			bw.Write (file_name);
 
 			ArrayList list = new ArrayList ();
 			foreach (MethodEntry entry in methods)
@@ -409,7 +400,7 @@ namespace Mono.CSharp.Debugger
 				if (creating)
 					throw new InvalidOperationException ();
 
-				BinaryReader reader = file.BinaryReader;
+				MyBinaryReader reader = file.BinaryReader;
 				int old_pos = (int) reader.BaseStream.Position;
 
 				reader.BaseStream.Position = NamespaceTableOffset;
@@ -530,9 +521,6 @@ namespace Mono.CSharp.Debugger
 		public readonly int Token;
 		public readonly int StartRow;
 		public readonly int EndRow;
-		[Obsolete("", true)]
-		public readonly int ClassTypeIndex;
-		public readonly int NumParameters;
 		public readonly int NumLocals;
 		public readonly int NumLineNumbers;
 		public readonly int NamespaceID;
@@ -547,14 +535,12 @@ namespace Mono.CSharp.Debugger
 		#endregion
 
 		int file_offset;
-		string name;
 
 		public readonly int Index;
 		public readonly SourceFileEntry SourceFile;
 		public readonly LineNumberEntry[] LineNumbers;
 		public readonly int[] LocalTypeIndices;
 		public readonly LocalVariableEntry[] Locals;
-		public readonly Type[] LocalTypes;
 		public readonly LexicalBlockEntry[] LexicalBlocks;
 
 		public readonly MonoSymbolFile SymbolFile;
@@ -563,15 +549,7 @@ namespace Mono.CSharp.Debugger
 			get { return 52; }
 		}
 
-		public string Name {
-			get { return name; }
-		}
-
-		public MethodBase MethodBase {
-			get { return MonoDebuggerSupport.GetMethod (SymbolFile.Assembly, Token); }
-		}
-
-		internal MethodEntry (MonoSymbolFile file, BinaryReader reader, int index)
+		internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index)
 		{
 			this.SymbolFile = file;
 			this.Index = index;
@@ -579,8 +557,6 @@ namespace Mono.CSharp.Debugger
 			Token = reader.ReadInt32 ();
 			StartRow = reader.ReadInt32 ();
 			EndRow = reader.ReadInt32 ();
-			reader.ReadInt32 ();
-			NumParameters = reader.ReadInt32 ();
 			NumLocals = reader.ReadInt32 ();
 			NumLineNumbers = reader.ReadInt32 ();
 			NameOffset = reader.ReadInt32 ();
@@ -592,8 +568,6 @@ namespace Mono.CSharp.Debugger
 			NamespaceID = reader.ReadInt32 ();
 			LocalNamesAmbiguous = reader.ReadInt32 () != 0;
 
-			name = file.ReadString (NameOffset);
-
 			SourceFile = file.GetSourceFile (SourceFileIndex);
 
 			if (LineNumberTableOffset != 0) {
@@ -613,15 +587,9 @@ namespace Mono.CSharp.Debugger
 				reader.BaseStream.Position = LocalVariableTableOffset;
 
 				Locals = new LocalVariableEntry [NumLocals];
-				LocalTypes = new Type [NumLocals];
 
-				Assembly ass = file.Assembly;
-
-				for (int i = 0; i < NumLocals; i++) {
+				for (int i = 0; i < NumLocals; i++)
 					Locals [i] = new LocalVariableEntry (reader);
-					LocalTypes [i] = MonoDebuggerSupport.GetLocalTypeFromSignature (
-						ass, Locals [i].Signature);
-				}
 
 				reader.BaseStream.Position = old_pos;
 			}
@@ -632,8 +600,6 @@ namespace Mono.CSharp.Debugger
 
 				LocalTypeIndices = new int [NumLocals];
 
-				for (int i = 0; i < NumParameters; i++)
-					reader.ReadInt32 ();
 				for (int i = 0; i < NumLocals; i++)
 					LocalTypeIndices [i] = reader.ReadInt32 ();
 
@@ -653,13 +619,11 @@ namespace Mono.CSharp.Debugger
 		}
 
 		internal MethodEntry (MonoSymbolFile file, SourceFileEntry source,
-				      string name, int token, int num_params,
-				      LocalVariableEntry[] locals, LineNumberEntry[] lines,
-				      LexicalBlockEntry[] blocks, int start_row, int end_row,
-				      int namespace_id)
+				      string name, int token, LocalVariableEntry[] locals,
+				      LineNumberEntry[] lines, LexicalBlockEntry[] blocks,
+				      int start_row, int end_row, int namespace_id)
 		{
 			this.SymbolFile = file;
-			this.name = name;
 
 			Index = file.GetNextMethodIndex ();
 
@@ -675,7 +639,8 @@ namespace Mono.CSharp.Debugger
 			LineNumbers = BuildLineNumberTable (lines);
 			NumLineNumbers = LineNumbers.Length;
 
-			NumParameters = num_params;
+			file.NumLineNumbers += NumLineNumbers;
+
 			NumLocals = locals != null ? locals.Length : 0;
 			Locals = locals;
 
@@ -760,15 +725,12 @@ namespace Mono.CSharp.Debugger
 			return retval;
 		}
 
-		internal MethodSourceEntry Write (MonoSymbolFile file, BinaryWriter bw)
+		internal MethodSourceEntry Write (MonoSymbolFile file, MyBinaryWriter bw)
 		{
 			NameOffset = (int) bw.BaseStream.Position;
-			file.WriteString (bw, name);
 
 			TypeIndexTableOffset = (int) bw.BaseStream.Position;
 
-			for (int i = 0; i < NumParameters; i++)
-				bw.Write (-1);
 			for (int i = 0; i < NumLocals; i++)
 				bw.Write (LocalTypeIndices [i]);
 
@@ -791,8 +753,6 @@ namespace Mono.CSharp.Debugger
 			bw.Write (Token);
 			bw.Write (StartRow);
 			bw.Write (EndRow);
-			bw.Write (-1);
-			bw.Write (NumParameters);
 			bw.Write (NumLocals);
 			bw.Write (NumLineNumbers);
 			bw.Write (NameOffset);
@@ -826,10 +786,9 @@ namespace Mono.CSharp.Debugger
 
 		public override string ToString ()
 		{
-			return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7}:{8} - {5}]",
+			return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7} - {5}]",
 					      Index, Token, SourceFileIndex, StartRow, EndRow,
-					      SourceFile, NumParameters, NumLocals,
-					      NumLineNumbers);
+					      SourceFile, NumLocals, NumLineNumbers);
 		}
 	}
 
@@ -850,26 +809,26 @@ namespace Mono.CSharp.Debugger
 			this.UsingClauses = using_clauses != null ? using_clauses : new string [0];
 		}
 
-		internal NamespaceEntry (MonoSymbolFile file, BinaryReader reader)
+		internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader)
 		{
-			Name = file.ReadString ();
-			Index = reader.ReadInt32 ();
-			Parent = reader.ReadInt32 ();
+			Name = reader.ReadString ();
+			Index = reader.ReadLeb128 ();
+			Parent = reader.ReadLeb128 ();
 
-			int count = reader.ReadInt32 ();
+			int count = reader.ReadLeb128 ();
 			UsingClauses = new string [count];
 			for (int i = 0; i < count; i++)
-				UsingClauses [i] = file.ReadString ();
+				UsingClauses [i] = reader.ReadString ();
 		}
 
-		internal void Write (MonoSymbolFile file, BinaryWriter bw)
+		internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
 		{
-			file.WriteString (bw, Name);
-			bw.Write (Index);
-			bw.Write (Parent);
-			bw.Write (UsingClauses.Length);
+			bw.Write (Name);
+			bw.WriteLeb128 (Index);
+			bw.WriteLeb128 (Parent);
+			bw.WriteLeb128 (UsingClauses.Length);
 			foreach (string uc in UsingClauses)
-				file.WriteString (bw, uc);
+				bw.Write (uc);
 		}
 
 		public override string ToString ()

+ 191 - 418
mcs/class/Mono.CSharp.Debugger/MonoSymbolWriter.cs

@@ -32,273 +32,49 @@
 //
 
 using System;
-using System.Reflection;
-using System.Reflection.Emit;
 using System.Runtime.CompilerServices;
-using System.Diagnostics.SymbolStore;
 using System.Collections;
 using System.IO;
 	
-namespace Mono.CSharp.Debugger
+namespace Mono.CompilerServices.SymbolWriter
 {
-	internal class SourceFile : SourceFileEntry, ISymbolDocumentWriter
+	public interface ISourceFile
 	{
-		private ArrayList _methods = new ArrayList ();
-
-		public SourceFile (MonoSymbolFile file, string filename)
-			: base (file, filename)
-		{ }
-
-		public new SourceMethod[] Methods {
-			get {
-				SourceMethod[] retval = new SourceMethod [_methods.Count];
-				_methods.CopyTo (retval);
-				return retval;
-			}
-		}
-
-		public void AddMethod (SourceMethod method)
-		{
-			_methods.Add (method);
-		}
-
-		void ISymbolDocumentWriter.SetCheckSum (Guid algorithmId, byte[] checkSum)
-		{
-			throw new NotSupportedException ();
-		}
-
-		void ISymbolDocumentWriter.SetSource (byte[] source)
-		{
-			throw new NotSupportedException ();
+		SourceFileEntry Entry {
+			get;
 		}
 	}
 
-	internal class SourceMethod
+	public interface ISourceMethod
 	{
-		LineNumberEntry [] lines;
-		private ArrayList _locals;
-		private ArrayList _blocks;
-		private Stack _block_stack;
-		private int next_block_id = 0;
-
-		internal readonly MethodBase _method_base;
-		internal SourceFile _source_file;
-		internal int _token;
-		private int _namespace_id;
-		private LineNumberEntry _start, _end;
-		private MonoSymbolFile _file;
-
-		private LexicalBlockEntry _implicit_block;
-
-		internal SourceMethod (MonoSymbolFile file, SourceFile source_file,
-				       int startLine, int startColumn, int endLine, int endColumn,
-				       MethodBase method_base, int namespace_id)
-		{
-			this._file = file;
-			this._method_base = method_base;
-			this._source_file = source_file;
-			this._namespace_id = namespace_id;
-
-			this._start = new LineNumberEntry (startLine, 0);
-			this._end = new LineNumberEntry (endLine, 0);
-
-			this._implicit_block = new LexicalBlockEntry (0, 0);
+		string Name {
+			get;
 		}
 
-		public void StartBlock (int startOffset)
-		{
-			LexicalBlockEntry block = new LexicalBlockEntry (++next_block_id, startOffset);
-			if (_block_stack == null)
-				_block_stack = new Stack ();
-			_block_stack.Push (block);
-			if (_blocks == null)
-				_blocks = new ArrayList ();
-			_blocks.Add (block);
-		}
-
-		public void EndBlock (int endOffset)
-		{
-			LexicalBlockEntry block = (LexicalBlockEntry) _block_stack.Pop ();
-
-			block.Close (endOffset);
+		int NamespaceID {
+			get;
 		}
 
-		public LexicalBlockEntry[] Blocks {
-			get {
-				if (_blocks == null)
-					return new LexicalBlockEntry [0];
-				else {
-					LexicalBlockEntry[] retval = new LexicalBlockEntry [_blocks.Count];
-					_blocks.CopyTo (retval, 0);
-					return retval;
-				}
-			}
-		}
-
-		public LexicalBlockEntry CurrentBlock {
-			get {
-				if ((_block_stack != null) && (_block_stack.Count > 0))
-					return (LexicalBlockEntry) _block_stack.Peek ();
-				else
-					return _implicit_block;
-			}
-		}
-
-		public LineNumberEntry[] Lines {
-			get {
-				return lines;
-			}
-		}
-
-		public LocalVariableEntry[] Locals {
-			get {
-				if (_locals == null)
-					return new LocalVariableEntry [0];
-				else {
-					LocalVariableEntry[] retval = new LocalVariableEntry [_locals.Count];
-					_locals.CopyTo (retval, 0);
-					return retval;
-				}
-			}
-		}
-
-		public void AddLocal (string name, FieldAttributes attributes, byte[] signature)
-		{
-			if (_locals == null)
-				_locals = new ArrayList ();
-			_locals.Add (new LocalVariableEntry (name, attributes, signature, CurrentBlock.Index));
-		}
-
-		public MethodBase MethodBase {
-			get {
-				return _method_base;
-			}
-		}
-
-		public string FullName {
-			get {
-				return _method_base.DeclaringType.FullName + "." + _method_base.Name;
-			}
-		}
-
-		public Type ReturnType {
-			get {
-				if (_method_base is MethodInfo)
-					return ((MethodInfo)_method_base).ReturnType;
-				else if (_method_base is ConstructorInfo)
-					return _method_base.DeclaringType;
-				else
-					throw new NotSupportedException ();
-			}
-		}
-
-		public ParameterInfo[] Parameters {
-			get {
-				if (_method_base == null)
-					return new ParameterInfo [0];
-
-				ParameterInfo [] retval = _method_base.GetParameters ();
-				if (retval == null)
-					return new ParameterInfo [0];
-				else
-					return retval;
-			}
-		}
-
-		public SourceFile SourceFile {
-			get {
-				return _source_file;
-			}
-		}
-
-		public int Token {
-			get {
-				if (_token != 0)
-					return _token;
-				else
-					throw new NotSupportedException ();
-			}
-		}
-
-		public bool HasSource {
-			get {
-				return _source_file != null;
-			}
-		}
-
-		public LineNumberEntry Start {
-			get {
-				return _start;
-			}
-		}
-
-		public LineNumberEntry End {
-			get {
-				return _end;
-			}
-		}
-
-		public int NamespaceID {
-			get {
-				return _namespace_id;
-			}
-		}
-		
-		//
-		// Passes on the lines from the MonoSymbolWriter. This method is
-		// free to mutate the lns array, and it does.
-		//
-		internal void SetLineNumbers (LineNumberEntry [] lns, int count)
-		{
-			int pos = 0;
-			
-			int last_offset = -1;
-			int last_row = -1;
-			for (int i = 0; i < count; i++) {
-				LineNumberEntry line = lns [i];
-
-				if (line.Offset > last_offset) {
-					if (last_row >= 0)
-						lns [pos++] = new LineNumberEntry (last_row, last_offset);
-						
-					last_row = line.Row;
-					last_offset = line.Offset;
-				} else if (line.Row > last_row) {
-					last_row = line.Row;
-				}
-			}
-			
-			lines = new LineNumberEntry [count + ((last_row >= 0) ? 1 : 0)];
-			Array.Copy (lns, lines, pos);
-			if (last_row >= 0)
-				lines [pos] = new LineNumberEntry (last_row, last_offset);
+		int Token {
+			get;
 		}
 	}
 
-	public class MonoSymbolWriter : IMonoSymbolWriter
+	public class MonoSymbolWriter
 	{
-		protected ModuleBuilder module_builder;
 		protected ArrayList locals = null;
-		protected ArrayList orphant_methods = null;
 		protected ArrayList methods = null;
-		protected Hashtable sources = null;
-		private MonoSymbolFile file = null;
+		protected ArrayList sources = null;
+		protected readonly MonoSymbolFile file;
+		private string filename = null;
 		
 		LineNumberEntry [] current_method_lines;
 		int current_method_lines_pos = 0;
 
-		internal SourceMethod[] Methods {
+		internal ISourceFile[] Sources {
 			get {
-				SourceMethod[] retval = new SourceMethod [methods.Count];
-				methods.CopyTo (retval);
-				return retval;
-			}
-		}
-
-		internal SourceFile[] Sources {
-			get {
-				SourceFile[] retval = new SourceFile [sources.Count];
-				sources.Values.CopyTo (retval, 0);
+				ISourceFile[] retval = new ISourceFile [sources.Count];
+				sources.CopyTo (retval, 0);
 				return retval;
 			}
 		}
@@ -309,106 +85,27 @@ namespace Mono.CSharp.Debugger
 		// Interface IMonoSymbolWriter
 		//
 
-		public MonoSymbolWriter (ModuleBuilder mb)
+		public MonoSymbolWriter (string filename)
 		{
-			this.module_builder = mb;
 			this.methods = new ArrayList ();
-			this.sources = new Hashtable ();
-			this.orphant_methods = new ArrayList ();
+			this.sources = new ArrayList ();
 			this.locals = new ArrayList ();
 			this.file = new MonoSymbolFile ();
+
+			this.filename = filename + ".mdb";
 			
 			this.current_method_lines = new LineNumberEntry [50];
 		}
 
-		public void Close ()
-		{
-			throw new InvalidOperationException ();
-		}
-
-		public byte[] CreateSymbolFile (AssemblyBuilder assembly_builder)
-		{
-			DoFixups (assembly_builder);
-
-			return CreateOutput (assembly_builder);
-		}
-
-		public void CloseNamespace () {
-		}
-
-		// Create and return a new IMonoSymbolDocumentWriter.
-		public ISymbolDocumentWriter DefineDocument (string url,
-							     Guid language,
-							     Guid languageVendor,
-							     Guid documentType)
-		{
-			if (sources.ContainsKey (url))
-				return (ISymbolDocumentWriter)sources [url];
-			SourceFile source_info = new SourceFile (file, url);
-			sources.Add (url, source_info);
-			return source_info;
-		}
-
-		public void DefineField (
-			SymbolToken parent,
-			string name,
-			FieldAttributes attributes,
-			byte[] signature,
-			SymAddressKind addrKind,
-			int addr1,
-			int addr2,
-			int addr3)
-		{
-			throw new NotSupportedException ();
-		}
-
-		public void DefineGlobalVariable (
-			string name,
-			FieldAttributes attributes,
-			byte[] signature,
-			SymAddressKind addrKind,
-			int addr1,
-			int addr2,
-			int addr3)
-		{
-			throw new NotSupportedException ();
-		}
+		public void CloseNamespace ()
+		{ }
 
-		public void DefineLocalVariable (string name,
-						 FieldAttributes attributes,
-						 byte[] signature,
-						 SymAddressKind addrKind,
-						 int addr1,
-						 int addr2,
-						 int addr3,
-						 int startOffset,
-						 int endOffset)
+		public void DefineLocalVariable (string name, byte[] signature)
 		{
 			if (current_method == null)
 				return;
 
-			current_method.AddLocal (name, attributes, signature);
-		}
-
-		public void DefineParameter (string name,
-					     ParameterAttributes attributes,
-					     int sequence,
-					     SymAddressKind addrKind,
-					     int addr1,
-					     int addr2,
-					     int addr3)
-		{
-			throw new NotSupportedException ();
-		}
-
-		public void DefineSequencePoints (ISymbolDocumentWriter document,
-						  int[] offsets,
-						  int[] lines,
-						  int[] columns,
-						  int[] endLines,
-						  int[] endColumns)
-		{
-			throw new NotSupportedException ();
+			current_method.AddLocal (name, signature);
 		}
 
 		public void MarkSequencePoint (int offset, int line, int column)
@@ -425,63 +122,40 @@ namespace Mono.CSharp.Debugger
 			current_method_lines [current_method_lines_pos++] = new LineNumberEntry (line, offset);
 		}
 
-		public void Initialize (IntPtr emitter, string filename, bool fFullBuild)
+		public void OpenMethod (ISourceFile file, ISourceMethod method,
+					int startRow, int startColumn,
+					int endRow, int endColumn)
 		{
-			throw new NotSupportedException ();
-		}
-
-		public void OpenMethod (SymbolToken symbol_token)
-		{
-			throw new NotSupportedException ();
-		}
-
-		public void SetMethodSourceRange (ISymbolDocumentWriter startDoc,
-						  int startLine, int startColumn,
-						  ISymbolDocumentWriter endDoc,
-						  int endLine, int endColumn)
-		{
-			throw new NotSupportedException ();
-		}
-
-		public void OpenMethod (ISymbolDocumentWriter document, int startLine, int startColumn,
-					int endLine, int endColumn, MethodBase method, int namespace_id)
-		{
-			SourceFile source_info = document as SourceFile;
-
-			if ((source_info == null) || (method == null))
-				throw new NullReferenceException ();
-
-			current_method = new SourceMethod (file, source_info, startLine, startColumn,
-							   endLine, endColumn, method, namespace_id);
+			SourceMethod source = new SourceMethod (
+				file, method, startRow, startColumn, endRow, endColumn);
 
+			current_method = source;
 			methods.Add (current_method);
-			source_info.AddMethod (current_method);
 		}
 
 		public void CloseMethod ()
 		{
-			current_method.SetLineNumbers (current_method_lines, current_method_lines_pos);
+			current_method.SetLineNumbers (
+				current_method_lines, current_method_lines_pos);
 			current_method_lines_pos = 0;
 			
 			current_method = null;
 		}
 
-		public int DefineNamespace (string name, ISymbolDocumentWriter document,
-					    string[] using_clauses, int parent)
+		public SourceFileEntry DefineDocument (string url)
 		{
-			if ((document == null) || (using_clauses == null))
-				throw new NullReferenceException ();
-			if (!(document is SourceFile))
-				throw new ArgumentException ();
-
-			SourceFile source_info = (SourceFile) document;
-
-			return source_info.DefineNamespace (name, using_clauses, parent);
+			SourceFileEntry entry = new SourceFileEntry (file, url);
+			sources.Add (entry);
+			return entry;
 		}
 
-		public void OpenNamespace (string name)
+		public int DefineNamespace (string name, SourceFileEntry source,
+					    string[] using_clauses, int parent)
 		{
-			throw new NotSupportedException ();
+			if ((source == null) || (using_clauses == null))
+				throw new NullReferenceException ();
+
+			return source.DefineNamespace (name, using_clauses, parent);
 		}
 
 		public int OpenScope (int startOffset)
@@ -501,71 +175,170 @@ namespace Mono.CSharp.Debugger
 			current_method.EndBlock (endOffset);
 		}
 
-		public void SetScopeRange (int scopeID, int startOffset, int endOffset)
+		protected byte[] CreateOutput (Guid guid)
 		{
-			throw new NotSupportedException ();
-		}
+			foreach (SourceMethod method in methods) {
+				method.SourceFile.Entry.DefineMethod (
+					method.Method.Name, method.Method.Token,
+					method.Locals, method.Lines, method.Blocks,
+					method.Start.Row, method.End.Row,
+					method.Method.NamespaceID);
+			}
 
-		public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
-		{
-			throw new NotSupportedException ();
+			return file.CreateSymbolFile (guid);
 		}
 
-		public void SetUnderlyingWriter (IntPtr underlyingWriter)
+		public void WriteSymbolFile (Guid guid)
 		{
-			throw new NotSupportedException ();
+			using (FileStream stream = new FileStream (
+				       filename, FileMode.Create, FileAccess.Write)) {
+				byte[] data = CreateOutput (guid);
+				stream.Write (data, 0, data.Length);
+			}
 		}
 
-		public void SetUserEntryPoint (SymbolToken entryMethod)
+		protected class SourceMethod
 		{
-			throw new NotSupportedException ();
-		}
+			LineNumberEntry [] lines;
+			private ArrayList _locals;
+			private ArrayList _blocks;
+			private Stack _block_stack;
+			private int next_block_id = 0;
+			private ISourceMethod _method;
+			private ISourceFile _file;
+			private LineNumberEntry _start, _end;
 
-		public void UsingNamespace (string fullName)
-		{
-			throw new NotSupportedException ();
-		}
+			private LexicalBlockEntry _implicit_block;
 
-		//
-		// MonoSymbolWriter implementation
-		//
-		protected void DoFixups (Assembly assembly)
-		{
-			foreach (SourceMethod method in methods) {
-				if (method._method_base is MethodBuilder) {
-					MethodBuilder mb = (MethodBuilder) method._method_base;
-					method._token = mb.GetToken ().Token;
-				} else if (method._method_base is ConstructorBuilder) {
-					ConstructorBuilder cb = (ConstructorBuilder) method._method_base;
-					method._token = cb.GetToken ().Token;
-				} else
-					throw new NotSupportedException ();
-
-				if (method.SourceFile == null)
-					orphant_methods.Add (method);
+			public SourceMethod (ISourceFile file, ISourceMethod method,
+					     int startLine, int startColumn,
+					     int endLine, int endColumn)
+			{
+				this._file = file;
+				this._method = method;
+
+				this._start = new LineNumberEntry (startLine, 0);
+				this._end = new LineNumberEntry (endLine, 0);
+
+				this._implicit_block = new LexicalBlockEntry (0, 0);
 			}
-		}
 
-		protected byte[] CreateOutput (Assembly assembly)
-		{
-			foreach (SourceMethod method in Methods) {
-				if (!method.HasSource) {
-					Console.WriteLine ("INGORING METHOD: {0}", method);
-					continue;
+			public void StartBlock (int startOffset)
+			{
+				LexicalBlockEntry block = new LexicalBlockEntry (
+					++next_block_id, startOffset);
+				if (_block_stack == null)
+					_block_stack = new Stack ();
+				_block_stack.Push (block);
+				if (_blocks == null)
+					_blocks = new ArrayList ();
+				_blocks.Add (block);
+			}
+
+			public void EndBlock (int endOffset)
+			{
+				LexicalBlockEntry block =
+					(LexicalBlockEntry) _block_stack.Pop ();
+
+				block.Close (endOffset);
+			}
+
+			public LexicalBlockEntry[] Blocks {
+				get {
+					if (_blocks == null)
+						return new LexicalBlockEntry [0];
+					else {
+						LexicalBlockEntry[] retval =
+							new LexicalBlockEntry [_blocks.Count];
+						_blocks.CopyTo (retval, 0);
+						return retval;
+					}
+				}
+			}
+
+			public LexicalBlockEntry CurrentBlock {
+				get {
+					if ((_block_stack != null) && (_block_stack.Count > 0))
+						return (LexicalBlockEntry) _block_stack.Peek ();
+					else
+						return _implicit_block;
+				}
+			}
+
+			public LineNumberEntry[] Lines {
+				get {
+					return lines;
 				}
+			}
 
-				MethodBase mb = method.MethodBase;
-				ParameterInfo[] parameters = mb.GetParameters ();
-				int num_params = parameters != null ? parameters.Length : 0;
+			public LocalVariableEntry[] Locals {
+				get {
+					if (_locals == null)
+						return new LocalVariableEntry [0];
+					else {
+						LocalVariableEntry[] retval =
+							new LocalVariableEntry [_locals.Count];
+						_locals.CopyTo (retval, 0);
+						return retval;
+					}
+				}
+			}
 
-				method.SourceFile.DefineMethod (
-					mb.Name, method.Token, num_params, method.Locals,
-					method.Lines, method.Blocks, method.Start.Row,
-					method.End.Row, method.NamespaceID);
+			public void AddLocal (string name, byte[] signature)
+			{
+				if (_locals == null)
+					_locals = new ArrayList ();
+				_locals.Add (new LocalVariableEntry (
+						     name, signature, CurrentBlock.Index));
 			}
 
-			return file.CreateSymbolFile ();
+			public ISourceFile SourceFile {
+				get { return _file; }
+			}
+
+			public ISourceMethod Method {
+				get { return _method; }
+			}
+
+			public LineNumberEntry Start {
+				get { return _start; }
+			}
+
+			public LineNumberEntry End {
+				get { return _end; }
+			}
+
+			//
+			// Passes on the lines from the MonoSymbolWriter. This method is
+			// free to mutate the lns array, and it does.
+			//
+			internal void SetLineNumbers (LineNumberEntry [] lns, int count)
+			{
+				int pos = 0;
+
+				int last_offset = -1;
+				int last_row = -1;
+				for (int i = 0; i < count; i++) {
+					LineNumberEntry line = lns [i];
+
+					if (line.Offset > last_offset) {
+						if (last_row >= 0)
+							lns [pos++] = new LineNumberEntry (
+								last_row, last_offset);
+
+						last_row = line.Row;
+						last_offset = line.Offset;
+					} else if (line.Row > last_row) {
+						last_row = line.Row;
+					}
+				}
+			
+				lines = new LineNumberEntry [count + ((last_row >= 0) ? 1 : 0)];
+				Array.Copy (lns, lines, pos);
+				if (last_row >= 0)
+					lines [pos] = new LineNumberEntry (
+						last_row, last_offset);
+			}
 		}
 	}
 }
-