[interp] Reduce computation under calc_section mutex
[mono-project.git] / mcs / ilasm / codegen / GenericTypeInst.cs
blob5510500749b0f1de2d3f867771a525179ceaf3e8
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)
13 using System;
14 using System.Collections;
16 namespace Mono.ILASM {
18 public class GenericTypeInst : BaseGenericTypeRef {
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 ();
29 public GenericTypeInst (BaseClassRef class_ref, GenericArguments gen_args, bool is_valuetypeinst)
30 : this (class_ref, gen_args, is_valuetypeinst, null, null)
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)
38 if (class_ref is GenericTypeInst)
39 throw new InternalErrorException ("Cannot create nested GenericInst, '" +
40 class_ref.FullName + "' '" + gen_args.ToString () + "'");
42 this.class_ref = class_ref;
43 this.gen_args = gen_args;
44 is_added = false;
47 public override string FullName {
48 get { return class_ref.FullName + gen_args.ToString () + SigMod; }
51 public override BaseTypeRef Clone ()
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 () );
59 public override void MakeValueClass ()
61 class_ref.MakeValueClass ();
64 public override void ResolveNoTypeSpec (CodeGen code_gen)
66 if (is_resolved)
67 return;
69 class_ref.Resolve (code_gen);
70 p_gen_inst = (PEAPI.GenericTypeInst) class_ref.ResolveInstance (code_gen, gen_args);
72 type = Modify (code_gen, p_gen_inst);
74 is_resolved = true;
77 public override void Resolve (CodeGen code_gen)
79 ResolveNoTypeSpec (code_gen);
80 if (is_added)
81 return;
83 code_gen.PEFile.AddGenericClass ((PEAPI.GenericTypeInst) p_gen_inst);
84 is_added = true;
87 public override void Resolve (GenericParameters type_gen_params, GenericParameters method_gen_params)
89 gen_args.Resolve (type_gen_params, method_gen_params);
92 protected override BaseMethodRef CreateMethodRef (BaseTypeRef ret_type,
93 PEAPI.CallConv call_conv, string name, BaseTypeRef[] param, int gen_param_count)
95 throw new InternalErrorException ("Should not be called");
98 public override BaseMethodRef GetMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
99 string meth_name, BaseTypeRef[] param, int gen_param_count)
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;
109 return mr;
112 protected override IFieldRef CreateFieldRef (BaseTypeRef ret_type, string field_name)
114 /* Note: Using FullName here as we are caching in a static hashtable */
115 string key = FullName + ret_type.FullName + field_name;
117 IFieldRef fr = (IFieldRef) s_field_table [key];
119 if (fr == null) {
120 fr = new TypeSpecFieldRef (this, ret_type, field_name);
121 s_field_table [key] = fr;
124 return fr;