Implement mono_gc_alloc_fixed on Boehm to be uncollectable. This matches SGen behavio...
[mono.git] / mcs / class / corlib / System.Reflection.Emit / ConstructorBuilder.cs
1 //
2 // System.Reflection.Emit.ConstructorBuilder.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 #if !FULL_AOT_RUNTIME
34 using System;
35 using System.Collections.Generic;
36 using System.Reflection;
37 using System.Reflection.Emit;
38 using System.Globalization;
39 using System.Security;
40 using System.Security.Permissions;
41 using System.Runtime.InteropServices;
42 using System.Diagnostics.SymbolStore;
43
44 namespace System.Reflection.Emit {
45
46         [ComVisible (true)]
47         [ComDefaultInterface (typeof (_ConstructorBuilder))]
48         [ClassInterface (ClassInterfaceType.None)]
49         [StructLayout (LayoutKind.Sequential)]
50         public sealed class ConstructorBuilder : ConstructorInfo, _ConstructorBuilder {
51         
52 #pragma warning disable 169, 414
53                 private RuntimeMethodHandle mhandle;
54                 private ILGenerator ilgen;
55                 internal Type[] parameters;
56                 private MethodAttributes attrs;
57                 private MethodImplAttributes iattrs;
58                 private int table_idx;
59                 private CallingConventions call_conv;
60                 private TypeBuilder type;
61                 internal ParameterBuilder[] pinfo;
62                 private CustomAttributeBuilder[] cattrs;
63                 private bool init_locals = true;
64                 private Type[][] paramModReq;
65                 private Type[][] paramModOpt;
66                 private RefEmitPermissionSet[] permissions;
67 #pragma warning restore 169, 414
68
69                 internal ConstructorBuilder (TypeBuilder tb, MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] paramModReq, Type[][] paramModOpt)
70                 {
71                         attrs = attributes | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
72                         call_conv = callingConvention;
73                         if (parameterTypes != null) {
74                                 for (int i = 0; i < parameterTypes.Length; ++i)
75                                         if (parameterTypes [i] == null)
76                                                 throw new ArgumentException ("Elements of the parameterTypes array cannot be null", "parameterTypes");
77
78                                 this.parameters = new Type [parameterTypes.Length];
79                                 System.Array.Copy (parameterTypes, this.parameters, parameterTypes.Length);
80                         }
81                         type = tb;
82                         this.paramModReq = paramModReq;
83                         this.paramModOpt = paramModOpt;
84                         table_idx = get_next_table_index (this, 0x06, true);
85
86                         ((ModuleBuilder) tb.Module).RegisterToken (this, GetToken ().Token);
87                 }
88
89                 [MonoTODO]
90                 public override CallingConventions CallingConvention {
91                         get {
92                                 return call_conv;
93                         }
94                 }
95
96                 public bool InitLocals {
97                         get {
98                                 return init_locals;
99                         }
100                         set {
101                                 init_locals = value;
102                         }
103                 }
104
105                 internal TypeBuilder TypeBuilder {
106                         get {
107                                 return type;
108                         }
109                 }
110                 
111                 public override MethodImplAttributes GetMethodImplementationFlags ()
112                 {
113                         return iattrs;
114                 }
115
116                 public override ParameterInfo[] GetParameters ()
117                 {
118                         if (!type.is_created)
119                                 throw not_created ();
120
121                         return GetParametersInternal ();
122                 }
123
124                 internal override ParameterInfo [] GetParametersInternal ()
125                 {
126                         if (parameters == null)
127                                 return EmptyArray<ParameterInfo>.Value;
128
129                         ParameterInfo [] retval = new ParameterInfo [parameters.Length];
130                         for (int i = 0; i < parameters.Length; i++)
131                                 retval [i] = ParameterInfo.New (pinfo == null ? null
132                                         : pinfo [i + 1], parameters [i], this, i + 1);
133
134                         return retval;
135                 }
136                 
137                 internal override int GetParametersCount ()
138                 {
139                         if (parameters == null)
140                                 return 0;
141                         
142                         return parameters.Length;
143                 }
144
145                 internal override Type GetParameterType (int pos) {
146                         return parameters [pos];
147                 }
148
149                 internal MethodBase RuntimeResolve () {
150                         return type.RuntimeResolve ().GetConstructor (this);
151                 }
152
153                 public override Object Invoke (Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
154                 {
155                         throw not_supported ();
156                 }
157
158                 public override object Invoke (BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture)
159                 {
160                         throw not_supported ();
161                 }
162
163                 public override RuntimeMethodHandle MethodHandle {
164                         get {
165                                 throw not_supported ();
166                         }
167                 }
168
169                 public override MethodAttributes Attributes {
170                         get {
171                                 return attrs;
172                         }
173                 }
174
175                 public override Type ReflectedType {
176                         get {
177                                 return type;
178                         }
179                 }
180
181                 public override Type DeclaringType {
182                         get {
183                                 return type;
184                         }
185                 }
186
187                 [Obsolete]
188                 public Type ReturnType {
189                         get {
190                                 return null;
191                         }
192                 }
193
194                 public override string Name {
195                         get {
196                                 return (attrs & MethodAttributes.Static) != 0 ? ConstructorInfo.TypeConstructorName : ConstructorInfo.ConstructorName;
197                         }
198                 }
199
200                 public string Signature {
201                         get {
202                                 return "constructor signature";
203                         }
204                 }
205
206                 public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset)
207                 {
208 #if !MOBILE
209                         if (pset == null)
210                                 throw new ArgumentNullException ("pset");
211                         if ((action == SecurityAction.RequestMinimum) ||
212                                 (action == SecurityAction.RequestOptional) ||
213                                 (action == SecurityAction.RequestRefuse))
214                                 throw new ArgumentOutOfRangeException ("action", "Request* values are not permitted");
215
216                         RejectIfCreated ();
217
218                         if (permissions != null) {
219                                 /* Check duplicate actions */
220                                 foreach (RefEmitPermissionSet set in permissions)
221                                         if (set.action == action)
222                                                 throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction.");
223
224                                 RefEmitPermissionSet[] new_array = new RefEmitPermissionSet [permissions.Length + 1];
225                                 permissions.CopyTo (new_array, 0);
226                                 permissions = new_array;
227                         }
228                         else
229                                 permissions = new RefEmitPermissionSet [1];
230
231                         permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ());
232                         attrs |= MethodAttributes.HasSecurity;
233 #endif
234                 }
235
236                 public ParameterBuilder DefineParameter (int iSequence, ParameterAttributes attributes, string strParamName)
237                 {
238                         if (iSequence < 1 || iSequence > GetParametersCount ())
239                                 throw new ArgumentOutOfRangeException ("iSequence");
240                         if (type.is_created)
241                                 throw not_after_created ();
242
243                         ParameterBuilder pb = new ParameterBuilder (this, iSequence, attributes, strParamName);
244                         if (pinfo == null)
245                                 pinfo = new ParameterBuilder [parameters.Length + 1];
246                         pinfo [iSequence] = pb;
247                         return pb;
248                 }
249
250                 public override bool IsDefined (Type attributeType, bool inherit)
251                 {
252                         throw not_supported ();
253                 }
254
255                 public override object [] GetCustomAttributes (bool inherit)
256                 {
257                         throw not_supported ();
258                 }
259
260                 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
261                 {
262                         throw not_supported ();
263                 }
264
265                 public ILGenerator GetILGenerator ()
266                 {
267                         return GetILGenerator (64);
268                 }
269
270                 public ILGenerator GetILGenerator (int streamSize)
271                 {
272                         if (ilgen != null)
273                                 return ilgen;
274                         ilgen = new ILGenerator (type.Module, ((ModuleBuilder)type.Module).GetTokenGenerator (), streamSize);
275                         return ilgen;
276                 }
277
278                 public void SetMethodBody (byte[] il, int maxStack, byte[] localSignature,
279                         IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
280                 {
281                         var ilgen = GetILGenerator ();
282                         ilgen.Init (il, maxStack, localSignature, exceptionHandlers, tokenFixups);
283                 }
284
285
286                 public void SetCustomAttribute (CustomAttributeBuilder customBuilder)
287                 {
288                         if (customBuilder == null)
289                                 throw new ArgumentNullException ("customBuilder");
290
291                         string attrname = customBuilder.Ctor.ReflectedType.FullName;
292                         if (attrname == "System.Runtime.CompilerServices.MethodImplAttribute") {
293                                 byte[] data = customBuilder.Data;
294                                 int impla; // the (stupid) ctor takes a short or an int ... 
295                                 impla = (int)data [2];
296                                 impla |= ((int)data [3]) << 8;
297                                 SetImplementationFlags ((MethodImplAttributes)impla);
298                                 return;
299                         }
300                         if (cattrs != null) {
301                                 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
302                                 cattrs.CopyTo (new_array, 0);
303                                 new_array [cattrs.Length] = customBuilder;
304                                 cattrs = new_array;
305                         } else {
306                                 cattrs = new CustomAttributeBuilder [1];
307                                 cattrs [0] = customBuilder;
308                         }
309                 }
310
311                 [ComVisible (true)]
312                 public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute)
313                 {
314                         if (con == null)
315                                 throw new ArgumentNullException ("con");
316                         if (binaryAttribute == null)
317                                 throw new ArgumentNullException ("binaryAttribute");
318
319                         SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
320                 }
321
322                 public void SetImplementationFlags (MethodImplAttributes attributes)
323                 {
324                         if (type.is_created)
325                                 throw not_after_created ();
326
327                         iattrs = attributes;
328                 }
329
330                 public Module GetModule ()
331                 {
332                         return type.Module;
333                 }
334
335                 public MethodToken GetToken ()
336                 {
337                         return new MethodToken (0x06000000 | table_idx);
338                 }
339
340                 [MonoTODO]
341                 public void SetSymCustomAttribute (string name, byte[] data)
342                 {
343                         if (type.is_created)
344                                 throw not_after_created ();
345                 }
346
347                 public override Module Module {
348                         get {
349                                 return GetModule ();
350                         }
351                 }
352
353                 public override string ToString ()
354                 {
355                         return "ConstructorBuilder ['" + type.Name + "']";
356                 }
357
358                 internal void fixup ()
359                 {
360                         if (((attrs & (MethodAttributes.Abstract | MethodAttributes.PinvokeImpl)) == 0) && ((iattrs & (MethodImplAttributes.Runtime | MethodImplAttributes.InternalCall)) == 0)) {
361                         if ((ilgen == null) || (ilgen.ILOffset == 0))
362                                 throw new InvalidOperationException ("Method '" + Name + "' does not have a method body.");
363                         }
364                         if (ilgen != null)
365                                 ilgen.label_fixup (this);
366                 }
367
368                 internal void ResolveUserTypes () {
369                         TypeBuilder.ResolveUserTypes (parameters);
370                         if (paramModReq != null) {
371                                 foreach (var types in paramModReq)
372                                         TypeBuilder.ResolveUserTypes (types);
373                         }
374                         if (paramModOpt != null) {
375                                 foreach (var types in paramModOpt)
376                                         TypeBuilder.ResolveUserTypes (types);
377                         }
378                 }
379
380                 internal void FixupTokens (Dictionary<int, int> token_map, Dictionary<int, MemberInfo> member_map) {
381                         if (ilgen != null)
382                                 ilgen.FixupTokens (token_map, member_map);
383                 }
384                 
385                 internal void GenerateDebugInfo (ISymbolWriter symbolWriter)
386                 {
387                         if (ilgen != null && ilgen.HasDebugInfo) {
388                                 SymbolToken token = new SymbolToken (GetToken().Token);
389                                 symbolWriter.OpenMethod (token);
390                                 symbolWriter.SetSymAttribute (token, "__name", System.Text.Encoding.UTF8.GetBytes (Name));
391                                 ilgen.GenerateDebugInfo (symbolWriter);
392                                 symbolWriter.CloseMethod ();
393                         }
394                 }
395
396                 internal override int get_next_table_index (object obj, int table, bool inc)
397                 {
398                         return type.get_next_table_index (obj, table, inc);
399                 }
400
401                 private void RejectIfCreated ()
402                 {
403                         if (type.is_created)
404                                 throw new InvalidOperationException ("Type definition of the method is complete.");
405                 }
406
407                 private Exception not_supported ()
408                 {
409                         return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
410                 }
411
412                 private Exception not_after_created ()
413                 {
414                         return new InvalidOperationException ("Unable to change after type has been created.");
415                 }
416
417                 private Exception not_created ()
418                 {
419                         return new NotSupportedException ("The type is not yet created.");
420                 }
421
422                 void _ConstructorBuilder.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
423                 {
424                         throw new NotImplementedException ();
425                 }
426
427                 void _ConstructorBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
428                 {
429                         throw new NotImplementedException ();
430                 }
431
432                 void _ConstructorBuilder.GetTypeInfoCount (out uint pcTInfo)
433                 {
434                         throw new NotImplementedException ();
435                 }
436
437                 void _ConstructorBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
438                 {
439                         throw new NotImplementedException ();
440                 }
441         }
442 }
443 #endif