2 // Mono.ILASM.PeapiTypeRef
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
12 using System.Collections;
14 namespace Mono.ILASM {
16 protected PEAPI.Type type;
19 public Pair (PEAPI.Type type, string sig)
25 public override int GetHashCode ()
27 return type.GetHashCode () ^ sig.GetHashCode ();
30 public override bool Equals (Object o)
37 return (p.type == this.type && p.sig == this.sig);
45 public Triplet (PEAPI.Type type, string sig, string typeMod)
48 this.typeMod = typeMod;
51 public override int GetHashCode ()
53 return base.GetHashCode () ^ typeMod.GetHashCode ();
56 public override bool Equals (object o)
58 Triplet t = o as Triplet;
62 return t.type == type && t.sig == sig && t.typeMod == typeMod;
66 public class PeapiTypeRef {
68 private PEAPI.Type peapi_type;
69 private bool is_pinned;
70 private bool is_array;
72 private bool use_type_spec;
74 private static Hashtable type_table = new Hashtable ();
76 public PeapiTypeRef (PEAPI.Type peapi_type)
78 this.peapi_type = peapi_type;
82 use_type_spec = false;
85 public bool IsPinned {
86 get { return is_pinned; }
90 get { return is_array; }
94 get { return is_ref; }
97 public bool UseTypeSpec {
98 get { return use_type_spec; }
101 public PEAPI.Type PeapiType {
102 get { return peapi_type; }
105 public void MakeArray ()
109 use_type_spec = true;
112 Pair p = new Pair (peapi_type, "[]");
113 type = type_table [p] as PEAPI.Type;
115 type = new PEAPI.ZeroBasedArray (peapi_type);
116 type_table [p] = type;
121 public void MakeBoundArray (ArrayList bound_list)
123 use_type_spec = true;
126 int dimen = bound_list.Count;
127 int[] lower_array = new int[dimen];
128 int[] size_array = new int[dimen];
129 int [] lobounds = null;
131 int num_lower, num_sizes;
137 for (int i=0; i<bound_list.Count; i++) {
138 DictionaryEntry e = (DictionaryEntry) bound_list [i];
139 if (e.Key != TypeRef.Ellipsis)
142 if (e.Value != TypeRef.Ellipsis)
144 if (i + 1 < bound_list.Count)
149 p = new Pair (peapi_type, sigmod);
150 type = type_table [p] as PEAPI.Type;
156 num_sizes = num_lower = 0;
157 // TODO: There should probably be an error reported if
158 // something like [3...,3...5] is done
159 for (int i=0; i<dimen; i++) {
160 if (bound_list [i] == null)
163 DictionaryEntry bound = (DictionaryEntry) bound_list [i];
165 if (bound.Key != TypeRef.Ellipsis) {
166 /* Lower bound specified */
167 lower_array [i] = (int) bound.Key;
170 if (bound.Value != TypeRef.Ellipsis) {
171 size_array [i] = (int) bound.Value;
172 if (bound.Key != TypeRef.Ellipsis)
173 /* .Value is Upper bound eg [1...5] */
174 size_array [i] -= lower_array [i] - 1;
180 lobounds = new int [num_lower];
181 Array.Copy (lower_array, lobounds, num_lower);
185 sizes = new int [num_sizes];
186 Array.Copy (size_array, sizes, num_sizes);
189 peapi_type = new PEAPI.BoundArray (peapi_type,
190 (uint) dimen, lobounds, sizes);
191 type_table [p] = peapi_type;
194 public void MakeManagedPointer ()
197 use_type_spec = true;
200 Pair p = new Pair (peapi_type, "&");
201 type = type_table [p] as PEAPI.Type;
203 type = new PEAPI.ManagedPointer (peapi_type);
204 type_table [p] = type;
209 public void MakeUnmanagedPointer ()
212 use_type_spec = true;
214 Pair p = new Pair (peapi_type, "*");
215 type = type_table [p] as PEAPI.Type;
217 type = new PEAPI.UnmanagedPointer (peapi_type);
218 type_table [p] = type;
223 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
228 use_type_spec = true;
230 Pair p = new Triplet (peapi_type, modifier.ToString (), klass.FullName);
231 type = type_table [p] as PEAPI.Type;
233 type = GetType (code_gen, modifier, klass);
234 type_table [p] = type;
239 PEAPI.Type GetType (CodeGen code_gen, PEAPI.CustomModifier modifier, BaseTypeRef klass)
241 klass.Resolve (code_gen);
242 var bcr = klass as BaseClassRef;
244 return new PEAPI.CustomModifiedType (peapi_type, modifier, bcr.PeapiClass);
246 var pt = klass as PrimitiveTypeRef;
247 return new PEAPI.CustomModifiedType (peapi_type, modifier, code_gen.PEFile.AddPrimitiveType ((PEAPI.PrimitiveType) pt.PeapiType));
249 throw new NotSupportedException (klass.GetType ().ToString ());
252 public void MakePinned ()
254 use_type_spec = true;
258 public void Resolve (CodeGen code_gen)