Merge pull request #4248 from Unity-Technologies/boehm-gc-alloc-fixed
[mono.git] / mcs / ilasm / codegen / GenericTypeInst.cs
1 //
2 // Mono.ILASM.GenericTypeInst
3 //
4 // Author(s):
5 //  Jackson Harper (Jackson@LatitudeGeo.com)
6 //  Ankit Jain (JAnkit@novell.com)
7 //
8 // (C) 2003 Latitude Geographics Group, All rights reserved
9 // (C) 2005 Novell, Inc (http://www.novell.com)
10 //
11
12
13 using System;
14 using System.Collections;
15
16 namespace Mono.ILASM {
17
18         public class GenericTypeInst : BaseGenericTypeRef {
19
20                 private BaseClassRef class_ref;
21                 private PEAPI.GenericTypeInst p_gen_inst;
22                 const bool is_valuetypeinst = false;
23                 private GenericArguments gen_args;
24                 private bool is_added; /* Added to PEFile (to TypeSpec table) ? */
25                 /* Note: Using static hashtable here as GenericTypeInsts is not cached */
26                 private static Hashtable s_method_table = new Hashtable ();
27                 private static Hashtable s_field_table = new Hashtable ();
28
29                 public GenericTypeInst (BaseClassRef class_ref, GenericArguments gen_args, bool is_valuetypeinst)
30                         : this (class_ref, gen_args, is_valuetypeinst, null, null)
31                 {
32                 }
33
34                 public GenericTypeInst (BaseClassRef class_ref, GenericArguments gen_args, bool is_valuetypeinst,
35                                 string sig_mod, ArrayList conv_list)
36                         : base ("", is_valuetypeinst, conv_list, sig_mod)
37                 {
38                         if (class_ref is GenericTypeInst)
39                                 throw new InternalErrorException ("Cannot create nested GenericInst, '" +
40                                                         class_ref.FullName + "' '" + gen_args.ToString () + "'");
41
42                         this.class_ref = class_ref;
43                         this.gen_args = gen_args;
44                         is_added = false;
45                 }
46
47                 public override string FullName {
48                         get { return class_ref.FullName + gen_args.ToString () + SigMod; }
49                 }
50
51                 public override BaseTypeRef Clone ()
52                 {
53                         //Clone'd instance shares the class_ref and gen_args,
54                         //as its basically used to create modified types (arrays etc)
55                         return new GenericTypeInst (class_ref, gen_args, is_valuetypeinst, sig_mod, 
56                                         (ArrayList) ConversionList.Clone () );
57                 }
58
59                 public override void MakeValueClass ()
60                 {
61                         class_ref.MakeValueClass ();
62                 }
63
64                 public override void ResolveNoTypeSpec (CodeGen code_gen)
65                 {
66                         if (is_resolved)
67                                 return;
68
69                         class_ref.Resolve (code_gen);
70                         p_gen_inst = (PEAPI.GenericTypeInst) class_ref.ResolveInstance (code_gen, gen_args);
71
72                         type = Modify (code_gen, p_gen_inst);
73
74                         is_resolved = true;
75                 }
76
77                 public override void Resolve (CodeGen code_gen)
78                 {
79                         ResolveNoTypeSpec (code_gen);
80                         if (is_added)
81                                 return;
82
83                         code_gen.PEFile.AddGenericClass ((PEAPI.GenericTypeInst) p_gen_inst);
84                         is_added = true;
85                 }
86
87                 public override void Resolve (GenericParameters type_gen_params, GenericParameters method_gen_params)
88                 {
89                         gen_args.Resolve (type_gen_params, method_gen_params);
90                 }
91
92                 protected override BaseMethodRef CreateMethodRef (BaseTypeRef ret_type,
93                         PEAPI.CallConv call_conv, string name, BaseTypeRef[] param, int gen_param_count)
94                 {
95                         throw new InternalErrorException ("Should not be called");
96                 }
97
98                 public override BaseMethodRef GetMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
99                                 string meth_name, BaseTypeRef[] param, int gen_param_count)
100                 {
101                         /* Note: Using FullName here as we are caching in a static hashtable */
102                         string key = FullName + MethodDef.CreateSignature (ret_type, call_conv, meth_name, param, gen_param_count, true);
103                         TypeSpecMethodRef mr = s_method_table [key] as TypeSpecMethodRef;
104                         if (mr == null) {         
105                                 mr = new TypeSpecMethodRef (this, call_conv, ret_type, meth_name, param, gen_param_count);
106                                 s_method_table [key] = mr;
107                         }
108
109                         return mr;
110                 }
111
112                 protected override IFieldRef CreateFieldRef (BaseTypeRef ret_type, string field_name)
113                 {
114                         /* Note: Using FullName here as we are caching in a static hashtable */
115                         string key = FullName + ret_type.FullName + field_name;
116
117                         IFieldRef fr = (IFieldRef) s_field_table [key];
118
119                         if (fr == null) {
120                                 fr = new TypeSpecFieldRef (this, ret_type, field_name);
121                                 s_field_table [key] = fr;
122                         }
123
124                         return fr;
125                 }
126         }
127 }
128