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 private 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);
41 public class PeapiTypeRef {
43 private PEAPI.Type peapi_type;
44 private bool is_pinned;
45 private bool is_array;
47 private bool use_type_spec;
49 private static Hashtable type_table = new Hashtable ();
51 public PeapiTypeRef (PEAPI.Type peapi_type)
53 this.peapi_type = peapi_type;
57 use_type_spec = false;
60 public bool IsPinned {
61 get { return is_pinned; }
65 get { return is_array; }
69 get { return is_ref; }
72 public bool UseTypeSpec {
73 get { return use_type_spec; }
76 public PEAPI.Type PeapiType {
77 get { return peapi_type; }
80 public void MakeArray ()
87 Pair p = new Pair (peapi_type, "[]");
88 type = type_table [p] as PEAPI.Type;
90 type = new PEAPI.ZeroBasedArray (peapi_type);
91 type_table [p] = type;
96 public void MakeBoundArray (ArrayList bound_list)
101 int dimen = bound_list.Count;
102 int[] lower_array = new int[dimen];
103 int[] size_array = new int[dimen];
104 int [] lobounds = null;
106 int num_lower, num_sizes;
112 for (int i=0; i<bound_list.Count; i++) {
113 DictionaryEntry e = (DictionaryEntry) bound_list [i];
114 if (e.Key != TypeRef.Ellipsis)
117 if (e.Value != TypeRef.Ellipsis)
119 if (i + 1 < bound_list.Count)
124 p = new Pair (peapi_type, sigmod);
125 type = type_table [p] as PEAPI.Type;
131 num_sizes = num_lower = 0;
132 // TODO: There should probably be an error reported if
133 // something like [3...,3...5] is done
134 for (int i=0; i<dimen; i++) {
135 if (bound_list [i] == null)
138 DictionaryEntry bound = (DictionaryEntry) bound_list [i];
140 if (bound.Key != TypeRef.Ellipsis) {
141 /* Lower bound specified */
142 lower_array [i] = (int) bound.Key;
145 if (bound.Value != TypeRef.Ellipsis) {
146 size_array [i] = (int) bound.Value;
147 if (bound.Key != TypeRef.Ellipsis)
148 /* .Value is Upper bound eg [1...5] */
149 size_array [i] -= lower_array [i] - 1;
155 lobounds = new int [num_lower];
156 Array.Copy (lower_array, lobounds, num_lower);
160 sizes = new int [num_sizes];
161 Array.Copy (size_array, sizes, num_sizes);
164 peapi_type = new PEAPI.BoundArray (peapi_type,
165 (uint) dimen, lobounds, sizes);
166 type_table [p] = peapi_type;
169 public void MakeManagedPointer ()
172 use_type_spec = true;
175 Pair p = new Pair (peapi_type, "&");
176 type = type_table [p] as PEAPI.Type;
178 type = new PEAPI.ManagedPointer (peapi_type);
179 type_table [p] = type;
184 public void MakeUnmanagedPointer ()
187 use_type_spec = true;
189 Pair p = new Pair (peapi_type, "*");
190 type = type_table [p] as PEAPI.Type;
192 type = new PEAPI.UnmanagedPointer (peapi_type);
193 type_table [p] = type;
198 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
203 use_type_spec = true;
205 Pair p = new Pair (peapi_type, modifier.ToString ());
206 type = type_table [p] as PEAPI.Type;
208 type = GetType (code_gen, modifier, klass);
209 type_table [p] = type;
214 PEAPI.Type GetType (CodeGen code_gen, PEAPI.CustomModifier modifier, BaseTypeRef klass)
216 klass.Resolve (code_gen);
217 var bcr = klass as BaseClassRef;
219 return new PEAPI.CustomModifiedType (peapi_type, modifier, bcr.PeapiClass);
221 var pt = klass as PrimitiveTypeRef;
222 return new PEAPI.CustomModifiedType (peapi_type, modifier, code_gen.PEFile.AddPrimitiveType ((PEAPI.PrimitiveType) pt.PeapiType));
224 throw new NotSupportedException (klass.GetType ().ToString ());
227 public void MakePinned ()
229 use_type_spec = true;
233 public void Resolve (CodeGen code_gen)