// 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 param_list; 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.ArgumentNullException ("instr", " 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 void SetParamList (ArrayList param_list) { this.param_list = param_list; } /// /// 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 MethodBuilder Builder { get { return method_builder; } } public void Resolve (Class host) { Type return_type = host.CodeGen.TypeManager[RetType]; method_builder = host.TypeBuilder.DefineMethod (Name, Attrs, CallConv, return_type, CreateTypeList (host.CodeGen.TypeManager)); } /// /// /// public void Emit (Class host) { TypeBuilder tb = host.TypeBuilder; if (IsCtor) { } else { 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.Key); return; } ilgen.DeclareLocal (local_type); } } if (instructions != null) { foreach (InstrBase instr in instructions) instr.Emit (ilgen, host); } } } private Type[] CreateTypeList (TypeManager type_manager) { if (param_list == null) return new Type[0]; int count = param_list.Count; Type[] type_list = new Type[count]; for (int i=0; i