// Method.cs // (C) Sergey Chaban (serge@wildwestsoftware.com) using System; using System.Collections; using System.Reflection; using System.Reflection.Emit; namespace Mono.ILASM { public class MethodName { private static int methodCount = 0; private bool isCtor; private string name; /// /// public MethodName () : this ("M_" + (methodCount++)) { } /// /// /// public MethodName (string name) : this (name, false) { } /// /// /// /// public MethodName (string name, bool ctor) { this.name = name; this.isCtor = ctor; } /// /// public string Name { get { return name; } set { name = value; } } /// /// public bool IsCtor { get { return isCtor; } set { isCtor = value; } } } /// /// public class Method { private MethodName name; private MethodAttributes attrs; private CallingConventions callConv; private string retType; private MethodBuilder method_builder; private bool entry_point = false; private ArrayList instructions; private ArrayList local_list; /// /// public Method () { name = new MethodName (); attrs = 0; } /// /// public string Name { get { return name.Name; } set { name.Name = value; } } /// /// /// public void SetMethodName (MethodName name) { this.name = name; } /// /// public bool IsCtor { get { return name.IsCtor; } set { name.IsCtor = value; } } /// /// public string RetType { get { return retType; } set { retType = value; } } /// /// public MethodAttributes Attrs { get { return attrs; } set { attrs = value; } } /// /// public CallingConventions CallConv { get { return callConv; } set { callConv = value; } } /// /// public bool IsEntryPoint { get { return entry_point; } set { entry_point = value; } } /// /// /// public void AddInstruction (InstrBase instr) { if (instr == null) { throw new System.NullReferenceException (" instruction"); } if (instructions == null) { this.instructions = new ArrayList (); } instructions.Add (instr); } public void AddLocal (DictionaryEntry local) { if (local_list == null) local_list = new ArrayList (); local_list.Add (local); } /// /// public int InstrCount { get { return (instructions != null) ? instructions.Count : 0; } } /// /// /// public override string ToString () { return String.Format ("IL.Method [Name: {0}, Attrs: {1}, CallConv: {2}, RetType: {3}, Instr: {4}]", Name, Attrs, CallConv, RetType, InstrCount); } public MethodInfo Info { get { return method_builder; } } /// /// /// public void Emit (Class host) { TypeBuilder tb = host.TypeBuilder; if (IsCtor) { } else { Type rt = host.CodeGen.RefTypes.Lookup (RetType); method_builder = tb.DefineMethod (Name, Attrs, CallConv, rt, null); ILGenerator ilgen = method_builder.GetILGenerator (); if (local_list != null) { foreach (DictionaryEntry local in local_list) { Type local_type = host.CodeGen.TypeManager[(string)local.Key]; if (local_type == null) { Console.WriteLine ("Could not find type: {0}", local); return; } ilgen.DeclareLocal (local_type); } } if (instructions != null) { foreach (InstrBase instr in instructions) instr.Emit (ilgen, host.CodeGen); } } } } }