// 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