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 bool lower_set = false;
105 bool size_set = false;
106 bool prev_lower_set = true;
107 bool prev_size_set = true;
113 for (int i=0; i<bound_list.Count; i++) {
114 DictionaryEntry e = (DictionaryEntry) bound_list [i];
115 if (e.Key != TypeRef.Ellipsis)
118 if (e.Value != TypeRef.Ellipsis)
120 if (i + 1 < bound_list.Count)
125 p = new Pair (peapi_type, sigmod);
126 type = type_table [p] as PEAPI.Type;
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) {
136 DictionaryEntry bound = (DictionaryEntry) bound_list[i];
138 if (bound.Key != TypeRef.Ellipsis && prev_lower_set) {
139 lower_array[i] = (int) bound.Key;
142 prev_lower_set = false;
144 if (bound.Value != TypeRef.Ellipsis && prev_size_set) {
145 size_array[i] = (int) bound.Value;
148 prev_size_set = false;
152 if (lower_set && size_set) {
153 peapi_type = new PEAPI.BoundArray (peapi_type,
154 (uint) dimen, lower_array, size_array);
155 } else if (size_set) {
156 peapi_type = new PEAPI.BoundArray (peapi_type,
157 (uint) dimen, size_array);
159 peapi_type = new PEAPI.BoundArray (peapi_type, (uint) dimen);
162 type_table [p] = peapi_type;
165 public void MakeManagedPointer ()
168 use_type_spec = true;
171 Pair p = new Pair (peapi_type, "&");
172 type = type_table [p] as PEAPI.Type;
174 type = new PEAPI.ManagedPointer (peapi_type);
175 type_table [p] = type;
180 public void MakeUnmanagedPointer ()
183 use_type_spec = true;
185 Pair p = new Pair (peapi_type, "*");
186 type = type_table [p] as PEAPI.Type;
188 type = new PEAPI.UnmanagedPointer (peapi_type);
189 type_table [p] = type;
194 public void MakeCustomModified (CodeGen code_gen, PEAPI.CustomModifier modifier,
199 use_type_spec = true;
201 Pair p = new Pair (peapi_type, modifier.ToString ());
202 type = type_table [p] as PEAPI.Type;
204 klass.Resolve (code_gen);
205 type = new PEAPI.CustomModifiedType (peapi_type,
206 modifier, klass.PeapiClass);
207 type_table [p] = type;
212 public void MakePinned ()
214 use_type_spec = true;
218 public void Resolve (CodeGen code_gen)