Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/ilasm/codegen/MethodTable.cs')
-rw-r--r--mcs/ilasm/codegen/MethodTable.cs228
1 files changed, 228 insertions, 0 deletions
diff --git a/mcs/ilasm/codegen/MethodTable.cs b/mcs/ilasm/codegen/MethodTable.cs
new file mode 100644
index 00000000000..2ac19d11aab
--- /dev/null
+++ b/mcs/ilasm/codegen/MethodTable.cs
@@ -0,0 +1,228 @@
+//
+// Mono.ILASM.MethodTable.cs
+//
+// Author(s):
+// Jackson Harper (Jackson@LatitudeGeo.com)
+//
+// (C) 2003 Jackson Harper, All rights reserved
+//
+
+using PEAPI;
+using System;
+using System.Text;
+using System.Collections;
+
+namespace Mono.ILASM {
+
+
+ public delegate void MethodDefinedEvent (object sender, MethodDefinedEventArgs args);
+ public delegate void MethodReferencedEvent (object sender, MethodReferencedEventArgs args);
+
+ public class MethodEventArgs : EventArgs {
+
+ public readonly string Signature;
+ public readonly string Name;
+ public readonly TypeRef ReturnType;
+ public readonly Param[] ParamList;
+ public readonly bool IsInTable;
+
+ public MethodEventArgs (string signature, string name,
+ TypeRef return_type, Param[] param_list, bool is_in_table)
+ {
+ Signature = signature;
+ Name = name;
+ ReturnType = return_type;
+ ParamList = param_list;
+ IsInTable = is_in_table;
+ }
+ }
+
+ public class MethodDefinedEventArgs : MethodEventArgs {
+
+ public readonly MethAttr MethodAttributes;
+ public readonly ImplAttr ImplAttributes;
+ public readonly CallConv CallConv;
+
+ public MethodDefinedEventArgs (string signature, string name,
+ TypeRef return_type, Param[] param_list, bool is_in_table, MethAttr method_attr,
+ ImplAttr impl_attr, CallConv call_conv) : base (signature, name,
+ return_type, param_list, is_in_table)
+ {
+ MethodAttributes = method_attr;
+ ImplAttributes = impl_attr;
+ CallConv = call_conv;
+ }
+ }
+
+ public class MethodReferencedEventArgs : MethodEventArgs {
+
+ public MethodReferencedEventArgs (string signature, string name,
+ TypeRef return_type, Param[] param_list, bool is_in_table) : base (signature, name,
+ return_type, param_list, is_in_table)
+ {
+
+ }
+ }
+
+
+ public class MethodTable {
+
+ private class MethodTableItem {
+
+ private static readonly int DefinedFlag = 2;
+
+ private int flags;
+
+ public ArrayList LocationList;
+ public MethodDef Method;
+
+ public MethodTableItem (MethodDef method, Location location)
+ {
+ flags = 0;
+ Method = method;
+ LocationList = new ArrayList ();
+ LocationList.Add (location);
+ }
+
+ public bool Defined {
+ get { return ((flags & DefinedFlag) != 0); }
+ set {
+ if (value)
+ flags |= DefinedFlag;
+ else
+ flags ^= DefinedFlag;
+ }
+ }
+ }
+
+ protected Hashtable table;
+ protected ClassDef parent_class;
+
+ public static event MethodReferencedEvent MethodReferencedEvent;
+ public static event MethodDefinedEvent MethodDefinedEvent;
+
+ public MethodTable (ClassDef parent_class)
+ {
+ this.parent_class = parent_class;
+ table = new Hashtable ();
+ }
+
+ public Method GetReference (string name, TypeRef return_type,
+ Param[] param_list, TypeRef[] param_type_list, Location location)
+ {
+ string signature = GetSignature (name, return_type, param_type_list);
+
+ if (MethodReferencedEvent != null)
+ MethodReferencedEvent (this, new MethodReferencedEventArgs (signature, name,
+ return_type, param_list, table.Contains (signature)));
+
+ MethodTableItem item = table[signature] as MethodTableItem;
+
+ if (item != null) {
+ item.LocationList.Add (location);
+ return item.Method;
+ }
+
+ MethodDef method = parent_class.AddMethod (name, return_type.Type,
+ param_list);
+
+ AddReferenced (signature, method, location);
+
+ return method;
+ }
+
+ public MethodDef AddDefinition (MethAttr method_attr, ImplAttr impl_attr, CallConv call_conv,
+ string name, TypeRef return_type, Param[] param_list,
+ TypeRef[] param_type_list, Location location)
+ {
+ string signature = GetSignature (name, return_type, param_type_list);
+
+ if (MethodDefinedEvent != null)
+ MethodDefinedEvent (this, new MethodDefinedEventArgs (signature, name,
+ return_type, param_list, table.Contains (signature), method_attr,
+ impl_attr, call_conv));
+
+ MethodTableItem item = (MethodTableItem) table[signature];
+
+ if (item == null) {
+ MethodDef method = parent_class.AddMethod (method_attr, impl_attr, name,
+ return_type.Type, param_list);
+ method.AddCallConv (call_conv);
+ AddDefined (signature, method, location);
+ return method;
+ }
+
+ item.Method.AddMethAttribute (method_attr);
+ item.Method.AddImplAttribute (impl_attr);
+ item.Method.AddCallConv (call_conv);
+ item.Defined = true;
+
+ return item.Method;
+ }
+
+ public bool CheckDefined ()
+ {
+ foreach (DictionaryEntry dic_entry in table) {
+ MethodTableItem table_item = (MethodTableItem) dic_entry.Value;
+ if (table_item.Defined)
+ continue;
+ Report.Error (String.Format ("Method: {0} is not defined.", dic_entry.Key));
+ }
+ return true;
+ }
+
+ protected string GetSignature (string name, TypeRef return_type,
+ TypeRef[] param_list)
+ {
+ StringBuilder builder = new StringBuilder ();
+
+ builder.Append (return_type.FullName);
+ builder.Append ('_');
+ builder.Append (name);
+ builder.Append ('(');
+
+ bool first = true;
+ foreach (TypeRef type_ref in param_list) {
+ if (!first)
+ builder.Append (',');
+ builder.Append (type_ref.FullName);
+ }
+ builder.Append (')');
+
+ return builder.ToString ();
+ }
+
+ protected void AddDefined (string signature, MethodDef method, Location location)
+ {
+ if (table.Contains (signature))
+ return;
+
+ MethodTableItem item = new MethodTableItem (method, location);
+ item.Defined = true;
+
+ table[signature] = item;
+ }
+
+ protected void AddReferenced (string signature, MethodDef method, Location location)
+ {
+ MethodTableItem item = new MethodTableItem (method, location);
+
+ table[signature] = item;
+ }
+
+ /// <summary>
+ /// If a method is allready defined throw an Error
+ /// </summary>
+ protected void CheckExists (string signature)
+ {
+ MethodTableItem item = table[signature] as MethodTableItem;
+
+ if ((item != null) && (item.Defined)) {
+ Report.Error (String.Format ("Method: {0} defined in multiple locations.",
+ signature));
+ }
+ }
+ }
+
+}
+