3 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 // System.Reflection.Emit/SignatureHelper.cs
29 // Paolo Molaro (lupus@ximian.com)
31 // (C) 2001 Ximian, Inc. http://www.ximian.com
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
41 namespace System.Reflection.Emit {
43 [ComDefaultInterface (typeof (_SignatureHelper))]
44 [ClassInterface (ClassInterfaceType.None)]
45 [StructLayout (LayoutKind.Sequential)]
46 public sealed class SignatureHelper : _SignatureHelper {
47 internal enum SignatureHelperType {
54 private ModuleBuilder module; // can be null in 2.0
55 private Type[] arguments;
56 private SignatureHelperType type;
57 private Type returnType;
58 private CallingConventions callConv;
59 private CallingConvention unmanagedCallConv;
60 #pragma warning disable 649
61 private Type[][] modreqs;
62 private Type[][] modopts;
63 #pragma warning restore 649
65 internal SignatureHelper (ModuleBuilder module, SignatureHelperType type)
71 public static SignatureHelper GetFieldSigHelper (Module mod)
73 if (mod != null && !(mod is ModuleBuilder))
74 throw new ArgumentException ("ModuleBuilder is expected");
76 return new SignatureHelper ((ModuleBuilder) mod, SignatureHelperType.HELPER_FIELD);
79 public static SignatureHelper GetLocalVarSigHelper (Module mod)
81 if (mod != null && !(mod is ModuleBuilder))
82 throw new ArgumentException ("ModuleBuilder is expected");
84 return new SignatureHelper ((ModuleBuilder) mod, SignatureHelperType.HELPER_LOCAL);
87 public static SignatureHelper GetLocalVarSigHelper ()
89 return new SignatureHelper (null, SignatureHelperType.HELPER_LOCAL);
92 public static SignatureHelper GetMethodSigHelper (CallingConventions callingConvention, Type returnType)
94 return GetMethodSigHelper (null, callingConvention, (CallingConvention)0, returnType, null);
97 public static SignatureHelper GetMethodSigHelper (CallingConvention unmanagedCallingConvention, Type returnType)
99 return GetMethodSigHelper (null, CallingConventions.Standard, unmanagedCallingConvention, returnType, null);
102 public static SignatureHelper GetMethodSigHelper (Module mod, CallingConventions callingConvention, Type returnType)
104 return GetMethodSigHelper (mod, callingConvention, (CallingConvention)0, returnType, null);
107 public static SignatureHelper GetMethodSigHelper (Module mod, CallingConvention unmanagedCallConv, Type returnType)
109 return GetMethodSigHelper (mod, CallingConventions.Standard, unmanagedCallConv, returnType, null);
112 public static SignatureHelper GetMethodSigHelper (Module mod, Type returnType, Type[] parameterTypes)
114 return GetMethodSigHelper (mod, CallingConventions.Standard, (CallingConvention)0, returnType, parameterTypes);
117 [MonoTODO("Not implemented")]
118 public static SignatureHelper GetPropertySigHelper (Module mod, Type returnType, Type[] parameterTypes)
120 throw new NotImplementedException ();
123 [MonoTODO("Not implemented")]
124 public static SignatureHelper GetPropertySigHelper (Module mod, Type returnType,
125 Type [] requiredReturnTypeCustomModifiers,
126 Type [] optionalReturnTypeCustomModifiers,
127 Type [] parameterTypes,
128 Type [] [] requiredParameterTypeCustomModifiers,
129 Type [] [] optionalParameterTypeCustomModifiers)
131 throw new NotImplementedException ();
135 [MonoTODO("Not implemented")]
136 public static SignatureHelper GetPropertySigHelper (Module mod,
137 CallingConventions callingConvention,
139 Type [] requiredReturnTypeCustomModifiers,
140 Type [] optionalReturnTypeCustomModifiers,
141 Type [] parameterTypes,
142 Type [] [] requiredParameterTypeCustomModifiers,
143 Type [] [] optionalParameterTypeCustomModifiers)
145 throw new NotImplementedException ();
150 // Grows the given array, and returns the index where the element
153 static int AppendArray (ref Type [] array, Type t)
156 Type[] new_a = new Type [array.Length + 1];
157 System.Array.Copy (array, new_a, array.Length);
158 new_a [array.Length] = t;
160 return array.Length-1;
162 array = new Type [1];
169 // Appends the given type array @t into the @array passed at
170 // position @pos. If there is no array, it gets created
172 // This allows adding data to a null array at position 5 for
173 // example, creating 4 empty slots before the slot where @t
177 static void AppendArrayAt (ref Type [][] array, Type [] t, int pos)
179 int top = Math.Max (pos, array == null ? 0 : array.Length);
180 Type[][] new_a = new Type [top+1][];
182 System.Array.Copy (array, new_a, top);
187 static void ValidateParameterModifiers (string name, Type [] parameter_modifiers)
189 foreach (Type modifier in parameter_modifiers){
190 if (modifier == null)
191 throw new ArgumentNullException (name);
192 if (modifier.IsArray)
193 throw new ArgumentException (Locale.GetText ("Array type not permitted"), name);
194 if (modifier.ContainsGenericParameters)
195 throw new ArgumentException (Locale.GetText ("Open Generic Type not permitted"), name);
199 static void ValidateCustomModifier (int n, Type [][] custom_modifiers, string name)
201 if (custom_modifiers == null)
204 if (custom_modifiers.Length != n)
205 throw new ArgumentException (
207 String.Format ("Custom modifiers length `{0}' does not match the size of the arguments")));
209 foreach (Type [] parameter_modifiers in custom_modifiers){
210 if (parameter_modifiers == null)
213 ValidateParameterModifiers (name, parameter_modifiers);
217 static Exception MissingFeature ()
219 throw new NotImplementedException ("Mono does not currently support setting modOpt/modReq through SignatureHelper");
222 [MonoTODO("Currently we ignore requiredCustomModifiers and optionalCustomModifiers")]
223 public void AddArguments (Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
225 if (arguments == null)
226 throw new ArgumentNullException ("arguments");
229 if (requiredCustomModifiers != null || optionalCustomModifiers != null){
230 throw MissingFeature();
233 ValidateCustomModifier (arguments.Length, requiredCustomModifiers, "requiredCustomModifiers");
234 ValidateCustomModifier (arguments.Length, optionalCustomModifiers, "optionalCustomModifiers");
236 for (int i = 0; i < arguments.Length; i++){
237 AddArgument (arguments [i],
238 requiredCustomModifiers != null ? requiredCustomModifiers [i] : null,
239 optionalCustomModifiers != null ? optionalCustomModifiers [i] : null);
243 [MonoTODO ("pinned is ignored")]
244 public void AddArgument (Type argument, bool pinned)
246 AddArgument (argument);
249 public void AddArgument (Type argument, Type [] requiredCustomModifiers, Type [] optionalCustomModifiers)
251 if (argument == null)
252 throw new ArgumentNullException ("argument");
254 if (requiredCustomModifiers != null)
255 ValidateParameterModifiers ("requiredCustomModifiers", requiredCustomModifiers);
256 if (optionalCustomModifiers != null)
257 ValidateParameterModifiers ("optionalCustomModifiers", optionalCustomModifiers);
259 int p = AppendArray (ref arguments, argument);
260 if (requiredCustomModifiers != null)
261 AppendArrayAt (ref modreqs, requiredCustomModifiers, p);
262 if (optionalCustomModifiers != null)
263 AppendArrayAt (ref modopts, optionalCustomModifiers, p);
266 public void AddArgument (Type clsArgument)
268 if (clsArgument == null)
269 throw new ArgumentNullException ("clsArgument");
271 AppendArray (ref arguments, clsArgument);
274 [MonoTODO("Not implemented")]
275 public void AddSentinel ()
277 throw new NotImplementedException ();
280 static bool CompareOK (Type [][] one, Type [][] two)
286 } else if (two == null)
289 if (one.Length != two.Length)
292 for (int i = 0; i < one.Length; i++){
293 Type [] tone = one [i];
294 Type [] ttwo = two [i];
299 } else if (ttwo == null)
302 if (tone.Length != ttwo.Length)
305 for (int j = 0; j < tone.Length; j++){
306 Type uone = tone [j];
307 Type utwo = ttwo [j];
313 } else if (utwo == null)
316 if (!uone.Equals (utwo))
323 public override bool Equals (object obj)
325 SignatureHelper other = obj as SignatureHelper;
329 if (other.module != module ||
330 other.returnType != returnType ||
331 other.callConv != callConv ||
332 other.unmanagedCallConv != unmanagedCallConv)
335 if (arguments != null){
336 if (other.arguments == null)
338 if (arguments.Length != other.arguments.Length)
341 for (int i = 0; i < arguments.Length; i++)
342 if (!other.arguments [i].Equals (arguments [i]))
344 } else if (other.arguments != null)
347 return CompareOK (other.modreqs, modreqs) && CompareOK (other.modopts, modopts);
350 public override int GetHashCode ()
352 // Lame, but easy, and will work, and chances are
353 // you will only need a few of these.
357 [MethodImplAttribute(MethodImplOptions.InternalCall)]
358 internal extern byte[] get_signature_local ();
360 [MethodImplAttribute(MethodImplOptions.InternalCall)]
361 internal extern byte[] get_signature_field ();
363 public byte[] GetSignature ()
366 case SignatureHelperType.HELPER_LOCAL:
367 return get_signature_local ();
368 case SignatureHelperType.HELPER_FIELD:
369 return get_signature_field ();
371 throw new NotImplementedException ();
375 public override string ToString() {
376 return "SignatureHelper";
379 internal static SignatureHelper GetMethodSigHelper (Module mod, CallingConventions callingConvention, CallingConvention unmanagedCallingConvention, Type returnType,
382 if (mod != null && !(mod is ModuleBuilder))
383 throw new ArgumentException ("ModuleBuilder is expected");
385 if (returnType == null)
386 returnType = typeof (void);
388 if (returnType.IsUserType)
389 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
390 if (parameters != null) {
391 for (int i = 0; i < parameters.Length; ++i)
392 if (parameters [i].IsUserType)
393 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
397 SignatureHelper helper =
398 new SignatureHelper ((ModuleBuilder)mod, SignatureHelperType.HELPER_METHOD);
399 helper.returnType = returnType;
400 helper.callConv = callingConvention;
401 helper.unmanagedCallConv = unmanagedCallingConvention;
403 if (parameters != null) {
404 helper.arguments = new Type [parameters.Length];
405 for (int i = 0; i < parameters.Length; ++i)
406 helper.arguments [i] = parameters [i];
412 void _SignatureHelper.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
414 throw new NotImplementedException ();
417 void _SignatureHelper.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
419 throw new NotImplementedException ();
422 void _SignatureHelper.GetTypeInfoCount (out uint pcTInfo)
424 throw new NotImplementedException ();
427 void _SignatureHelper.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
429 throw new NotImplementedException ();