//
-// symbolwriter.cs: The symbol writer
+// symbolwriter.cs: The debug symbol writer
//
-// Author:
-// Martin Baulig (martin@ximian.com)
+// Authors: Martin Baulig (martin@ximian.com)
+// Marek Safar (marek.safar@gmail.com)
//
-// (C) 2003 Ximian, Inc.
+// Dual licensed under the terms of the MIT X11 or GNU GPL
+//
+// Copyright 2003 Ximian, Inc (http://www.ximian.com)
+// Copyright 2004-2010 Novell, Inc
//
using System;
-using System.Collections;
+
+#if STATIC
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
+#else
using System.Reflection;
using System.Reflection.Emit;
-using System.Diagnostics.SymbolStore;
+#endif
+
+using Mono.CompilerServices.SymbolWriter;
+
+namespace Mono.CSharp
+{
+ static class SymbolWriter
+ {
+#if !NET_4_0 && !STATIC
+ delegate int GetILOffsetFunc (ILGenerator ig);
+ static GetILOffsetFunc get_il_offset_func;
-namespace Mono.CSharp {
- public class SymbolWriter {
- ISymbolWriter symwriter;
- MethodInfo define_namespace;
- MethodInfo open_method;
+ delegate Guid GetGuidFunc (ModuleBuilder mb);
+ static GetGuidFunc get_guid_func;
- protected SymbolWriter (ISymbolWriter symwriter)
+ static void Initialize ()
{
- this.symwriter = symwriter;
+ var mi = typeof (ILGenerator).GetMethod (
+ "Mono_GetCurrentOffset",
+ BindingFlags.Static | BindingFlags.NonPublic);
+ if (mi == null)
+ throw new MissingMethodException ("Mono_GetCurrentOffset");
+
+ get_il_offset_func = (GetILOffsetFunc) System.Delegate.CreateDelegate (
+ typeof (GetILOffsetFunc), mi);
+
+ mi = typeof (ModuleBuilder).GetMethod (
+ "Mono_GetGuid",
+ BindingFlags.Static | BindingFlags.NonPublic);
+ if (mi == null)
+ throw new MissingMethodException ("Mono_GetGuid");
+
+ get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
+ typeof (GetGuidFunc), mi);
}
+#endif
- bool Initialize ()
+ static int GetILOffset (ILGenerator ig)
{
- Type type = symwriter.GetType ();
- define_namespace = type.GetMethod ("DefineNamespace", new Type[] {
- typeof (string), typeof (ISymbolDocumentWriter),
- typeof (string []), typeof (int) });
- if (define_namespace == null)
- return false;
+#if NET_4_0 || STATIC
+ return ig.ILOffset;
+#else
+ if (get_il_offset_func == null)
+ Initialize ();
- open_method = type.GetMethod ("OpenMethod", new Type[] {
- typeof (ISymbolDocumentWriter), typeof (int), typeof (int),
- typeof (int), typeof (int), typeof (MethodBase), typeof (int) });
- if (open_method == null)
- return false;
+ return get_il_offset_func (ig);
+#endif
+ }
- Location.DefineSymbolDocuments (this);
- Namespace.DefineNamespaces (this);
+ public static Guid GetGuid (ModuleBuilder module)
+ {
+#if NET_4_0 || STATIC
+ return module.ModuleVersionId;
+#else
+ if (get_guid_func == null)
+ Initialize ();
+
+ return get_guid_func (module);
+#endif
+ }
- return true;
+ public static bool HasSymbolWriter {
+ get { return symwriter != null; }
}
- public ISymbolDocumentWriter DefineDocument (string path)
+ public static MonoSymbolWriter symwriter;
+
+ public static void DefineLocalVariable (string name, LocalBuilder builder)
{
- return symwriter.DefineDocument (
- path, SymLanguageType.CSharp, SymLanguageVendor.Microsoft,
- SymDocumentType.Text);
+ if (symwriter != null) {
+ symwriter.DefineLocalVariable (builder.LocalIndex, name);
+ }
}
- public int DefineNamespace (string name, SourceFile file, string[] using_list, int parent)
+ public static SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id,
+ IMethodDef method)
{
- return (int) define_namespace.Invoke (symwriter, new object[] {
- name, file.SymbolDocument, using_list, parent });
+ if (symwriter != null)
+ return symwriter.OpenMethod (file, ns_id, method);
+ else
+ return null;
}
- public void OpenMethod (TypeContainer parent, MethodBase method, Location start, Location end)
+ public static void CloseMethod ()
{
- int ns_id = parent.Namespace.SymbolFileID;
- open_method.Invoke (symwriter, new object[] {
- start.SymbolDocument, start.Row, 0, end.Row, 0, method, ns_id });
+ if (symwriter != null)
+ symwriter.CloseMethod ();
}
- public void CloseMethod ()
+ public static int OpenScope (ILGenerator ig)
{
- symwriter.CloseMethod ();
+ if (symwriter != null) {
+ int offset = GetILOffset (ig);
+ return symwriter.OpenScope (offset);
+ } else {
+ return -1;
+ }
}
- public static SymbolWriter GetSymbolWriter (ModuleBuilder module)
+ public static void CloseScope (ILGenerator ig)
{
- ISymbolWriter symwriter = module.GetSymWriter ();
+ if (symwriter != null) {
+ int offset = GetILOffset (ig);
+ symwriter.CloseScope (offset);
+ }
+ }
- if (symwriter == null)
- return null;
+ public static int DefineNamespace (string name, CompileUnitEntry source,
+ string[] using_clauses, int parent)
+ {
+ if (symwriter != null)
+ return symwriter.DefineNamespace (name, source, using_clauses, parent);
+ else
+ return -1;
+ }
- SymbolWriter writer = new SymbolWriter (symwriter);
- if (!writer.Initialize ())
- return null;
+ public static void DefineAnonymousScope (int id)
+ {
+ if (symwriter != null)
+ symwriter.DefineAnonymousScope (id);
+ }
+
+ public static void DefineScopeVariable (int scope, LocalBuilder builder)
+ {
+ if (symwriter != null) {
+ symwriter.DefineScopeVariable (scope, builder.LocalIndex);
+ }
+ }
+
+ public static void DefineScopeVariable (int scope)
+ {
+ if (symwriter != null)
+ symwriter.DefineScopeVariable (scope, -1);
+ }
+
+ public static void DefineCapturedLocal (int scope_id, string name,
+ string captured_name)
+ {
+ if (symwriter != null)
+ symwriter.DefineCapturedLocal (scope_id, name, captured_name);
+ }
+
+ public static void DefineCapturedParameter (int scope_id, string name,
+ string captured_name)
+ {
+ if (symwriter != null)
+ symwriter.DefineCapturedParameter (scope_id, name, captured_name);
+ }
+
+ public static void DefineCapturedThis (int scope_id, string captured_name)
+ {
+ if (symwriter != null)
+ symwriter.DefineCapturedThis (scope_id, captured_name);
+ }
+
+ public static void DefineCapturedScope (int scope_id, int id, string captured_name)
+ {
+ if (symwriter != null)
+ symwriter.DefineCapturedScope (scope_id, id, captured_name);
+ }
+
+ public static void OpenCompilerGeneratedBlock (EmitContext ec)
+ {
+ if (symwriter != null) {
+ int offset = GetILOffset (ec.ig);
+ symwriter.OpenCompilerGeneratedBlock (offset);
+ }
+ }
+
+ public static void CloseCompilerGeneratedBlock (EmitContext ec)
+ {
+ if (symwriter != null) {
+ int offset = GetILOffset (ec.ig);
+ symwriter.CloseCompilerGeneratedBlock (offset);
+ }
+ }
+
+ public static void StartIteratorBody (EmitContext ec)
+ {
+ if (symwriter != null) {
+ int offset = GetILOffset (ec.ig);
+ symwriter.StartIteratorBody (offset);
+ }
+ }
+
+ public static void EndIteratorBody (EmitContext ec)
+ {
+ if (symwriter != null) {
+ int offset = GetILOffset (ec.ig);
+ symwriter.EndIteratorBody (offset);
+ }
+ }
+
+ public static void StartIteratorDispatcher (EmitContext ec)
+ {
+ if (symwriter != null) {
+ int offset = GetILOffset (ec.ig);
+ symwriter.StartIteratorDispatcher (offset);
+ }
+ }
- return writer;
+ public static void EndIteratorDispatcher (EmitContext ec)
+ {
+ if (symwriter != null) {
+ int offset = GetILOffset (ec.ig);
+ symwriter.EndIteratorDispatcher (offset);
+ }
+ }
+
+ public static void MarkSequencePoint (ILGenerator ig, Location loc)
+ {
+ if (symwriter != null) {
+ SourceFileEntry file = loc.SourceFile.SourceFileEntry;
+ int offset = GetILOffset (ig);
+ symwriter.MarkSequencePoint (
+ offset, file, loc.Row, loc.Column, loc.Hidden);
+ }
+ }
+
+ public static void Reset ()
+ {
+ symwriter = null;
}
}
}