1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
using System;
using System.Collections;
using System.Runtime.Serialization;
using C = Mono.CompilerServices.SymbolWriter;
using Cecil = Mono.Cecil;
using Mono.Debugger;
using Mono.Debugger.Backend;
namespace Mono.Debugger.Languages.Mono
{
internal class MonoFunctionType : TargetFunctionType
{
MonoClassType klass;
SourceFile file;
int start_row, end_row;
Cecil.MethodDefinition method_info;
TargetType return_type;
TargetType[] parameter_types;
bool has_return_type;
string name;
int token;
int load_handler;
internal MonoFunctionType (MonoClassType klass, Cecil.MethodDefinition mdef)
: base (klass.File.MonoLanguage)
{
this.klass = klass;
this.method_info = mdef;
this.token = MonoDebuggerSupport.GetMethodToken (mdef);
this.name = GetMethodName (mdef) + MonoSymbolFile.GetMethodSignature (mdef);
Cecil.TypeReference rtype;
if (mdef.IsConstructor) {
rtype = mdef.DeclaringType;
has_return_type = true;
} else {
rtype = mdef.ReturnType.ReturnType;
has_return_type = rtype.FullName != "System.Void";
}
return_type = klass.File.MonoLanguage.LookupMonoType (rtype);
parameter_types = new TargetType [mdef.Parameters.Count];
for (int i = 0; i < mdef.Parameters.Count; i++)
parameter_types [i] = klass.File.MonoLanguage.LookupMonoType (
mdef.Parameters[i].ParameterType);
}
internal MonoFunctionType (MonoClassType klass, Cecil.MethodDefinition mdef,
SourceFile file, int start_row, int end_row)
: this (klass, mdef)
{
this.file = file;
this.start_row = start_row;
this.end_row = end_row;
}
internal static string GetMethodName (Cecil.MethodDefinition mdef)
{
Cecil.GenericParameterCollection gen_params = mdef.GenericParameters;
if ((gen_params == null) || (gen_params.Count == 0))
return mdef.Name;
else
return mdef.Name + "`" + gen_params.Count;
}
public override bool HasClassType {
get { return false; }
}
public override TargetClassType ClassType {
get { throw new InvalidOperationException (); }
}
public override string Name {
get { return name; }
}
public override string FullName {
get { return klass.Name + '.' + name; }
}
public override bool IsByRef {
get { return true; }
}
public override bool IsStatic {
get { return method_info.IsStatic; }
}
public override bool IsConstructor {
get { return method_info.IsConstructor; }
}
public override TargetType ReturnType {
get { return return_type; }
}
public override bool HasReturnValue {
get { return has_return_type; }
}
public override TargetType[] ParameterTypes {
get { return parameter_types; }
}
public int Token {
get { return token; }
}
public override TargetClassType DeclaringType {
get { return klass; }
}
internal MonoClassType MonoClass {
get { return klass; }
}
internal Cecil.MethodDefinition MethodInfo {
get { return method_info; }
}
public override object MethodHandle {
get { return method_info; }
}
public override bool HasFixedSize {
get { return true; }
}
public override int Size {
get { return klass.File.TargetMemoryInfo.TargetAddressSize; }
}
public override bool HasSourceCode {
get { return file != null; }
}
public override SourceFile SourceFile {
get {
if (!HasSourceCode)
throw new InvalidOperationException ();
return file;
}
}
public override int StartRow {
get {
if (!HasSourceCode)
throw new InvalidOperationException ();
return start_row;
}
}
public override int EndRow {
get {
if (!HasSourceCode)
throw new InvalidOperationException ();
return end_row;
}
}
protected override TargetObject DoGetObject (TargetMemoryAccess target,
TargetLocation location)
{
throw new InvalidOperationException ();
}
public override bool IsManaged {
get { return true; }
}
internal override bool InsertBreakpoint (Thread target,
FunctionBreakpointHandle handle)
{
load_handler = klass.File.MonoLanguage.RegisterMethodLoadHandler (
target, this, handle);
return load_handler > 0;
}
internal override void RemoveBreakpoint (Thread target)
{
if (load_handler > 0) {
klass.File.MonoLanguage.RemoveMethodLoadHandler (target, load_handler);
load_handler = -1;
}
}
}
}
|