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
36 using System
.Reflection
;
37 using System
.Reflection
.Emit
;
38 using System
.Globalization
;
39 using System
.Runtime
.CompilerServices
;
40 using System
.Runtime
.InteropServices
;
42 namespace System
.Reflection
.Emit
{
44 [ComDefaultInterface (typeof (_SignatureHelper
))]
45 [ClassInterface (ClassInterfaceType
.None
)]
46 [StructLayout (LayoutKind
.Sequential
)]
47 public sealed class SignatureHelper
: _SignatureHelper
{
48 internal enum SignatureHelperType
{
55 private ModuleBuilder module
; // can be null in 2.0
56 private Type
[] arguments
;
57 private SignatureHelperType type
;
58 private Type returnType
;
59 private CallingConventions callConv
;
60 private CallingConvention unmanagedCallConv
;
61 #pragma warning disable 649
62 private Type
[][] modreqs
;
63 private Type
[][] modopts
;
64 #pragma warning restore 649
66 internal SignatureHelper (ModuleBuilder module
, SignatureHelperType type
)
72 public static SignatureHelper
GetFieldSigHelper (Module mod
)
74 if (mod
!= null && !(mod
is ModuleBuilder
))
75 throw new ArgumentException ("ModuleBuilder is expected");
77 return new SignatureHelper ((ModuleBuilder
) mod
, SignatureHelperType
.HELPER_FIELD
);
80 public static SignatureHelper
GetLocalVarSigHelper (Module mod
)
82 if (mod
!= null && !(mod
is ModuleBuilder
))
83 throw new ArgumentException ("ModuleBuilder is expected");
85 return new SignatureHelper ((ModuleBuilder
) mod
, SignatureHelperType
.HELPER_LOCAL
);
88 public static SignatureHelper
GetLocalVarSigHelper ()
90 return new SignatureHelper (null, SignatureHelperType
.HELPER_LOCAL
);
93 public static SignatureHelper
GetMethodSigHelper (CallingConventions callingConvention
, Type returnType
)
95 return GetMethodSigHelper (null, callingConvention
, (CallingConvention
)0, returnType
, null);
98 public static SignatureHelper
GetMethodSigHelper (CallingConvention unmanagedCallingConvention
, Type returnType
)
100 return GetMethodSigHelper (null, CallingConventions
.Standard
, unmanagedCallingConvention
, returnType
, null);
103 public static SignatureHelper
GetMethodSigHelper (Module mod
, CallingConventions callingConvention
, Type returnType
)
105 return GetMethodSigHelper (mod
, callingConvention
, (CallingConvention
)0, returnType
, null);
108 public static SignatureHelper
GetMethodSigHelper (Module mod
, CallingConvention unmanagedCallConv
, Type returnType
)
110 return GetMethodSigHelper (mod
, CallingConventions
.Standard
, unmanagedCallConv
, returnType
, null);
113 public static SignatureHelper
GetMethodSigHelper (Module mod
, Type returnType
, Type
[] parameterTypes
)
115 return GetMethodSigHelper (mod
, CallingConventions
.Standard
, (CallingConvention
)0, returnType
, parameterTypes
);
118 [MonoTODO("Not implemented")]
119 public static SignatureHelper
GetPropertySigHelper (Module mod
, Type returnType
, Type
[] parameterTypes
)
121 throw new NotImplementedException ();
124 [MonoTODO("Not implemented")]
125 public static SignatureHelper
GetPropertySigHelper (Module mod
, Type returnType
,
126 Type
[] requiredReturnTypeCustomModifiers
,
127 Type
[] optionalReturnTypeCustomModifiers
,
128 Type
[] parameterTypes
,
129 Type
[] [] requiredParameterTypeCustomModifiers
,
130 Type
[] [] optionalParameterTypeCustomModifiers
)
132 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 ();
149 // Grows the given array, and returns the index where the element
152 static int AppendArray (ref Type
[] array
, Type t
)
155 Type
[] new_a
= new Type
[array
.Length
+ 1];
156 System
.Array
.Copy (array
, new_a
, array
.Length
);
157 new_a
[array
.Length
] = t
;
159 return array
.Length
-1;
161 array
= new Type
[1];
168 // Appends the given type array @t into the @array passed at
169 // position @pos. If there is no array, it gets created
171 // This allows adding data to a null array at position 5 for
172 // example, creating 4 empty slots before the slot where @t
176 static void AppendArrayAt (ref Type
[][] array
, Type
[] t
, int pos
)
178 int top
= Math
.Max (pos
, array
== null ? 0 : array
.Length
);
179 Type
[][] new_a
= new Type
[top
+1][];
181 System
.Array
.Copy (array
, new_a
, top
);
186 static void ValidateParameterModifiers (string name
, Type
[] parameter_modifiers
)
188 foreach (Type modifier
in parameter_modifiers
){
189 if (modifier
== null)
190 throw new ArgumentNullException (name
);
191 if (modifier
.IsArray
)
192 throw new ArgumentException (Locale
.GetText ("Array type not permitted"), name
);
193 if (modifier
.ContainsGenericParameters
)
194 throw new ArgumentException (Locale
.GetText ("Open Generic Type not permitted"), name
);
198 static void ValidateCustomModifier (int n
, Type
[][] custom_modifiers
, string name
)
200 if (custom_modifiers
== null)
203 if (custom_modifiers
.Length
!= n
)
204 throw new ArgumentException (
206 String
.Format ("Custom modifiers length `{0}' does not match the size of the arguments")));
208 foreach (Type
[] parameter_modifiers
in custom_modifiers
){
209 if (parameter_modifiers
== null)
212 ValidateParameterModifiers (name
, parameter_modifiers
);
216 static Exception
MissingFeature ()
218 throw new NotImplementedException ("Mono does not currently support setting modOpt/modReq through SignatureHelper");
221 [MonoTODO("Currently we ignore requiredCustomModifiers and optionalCustomModifiers")]
222 public void AddArguments (Type
[] arguments
, Type
[][] requiredCustomModifiers
, Type
[][] optionalCustomModifiers
)
224 if (arguments
== null)
225 throw new ArgumentNullException ("arguments");
228 if (requiredCustomModifiers
!= null || optionalCustomModifiers
!= null){
229 throw MissingFeature();
232 ValidateCustomModifier (arguments
.Length
, requiredCustomModifiers
, "requiredCustomModifiers");
233 ValidateCustomModifier (arguments
.Length
, optionalCustomModifiers
, "optionalCustomModifiers");
235 for (int i
= 0; i
< arguments
.Length
; i
++){
236 AddArgument (arguments
[i
],
237 requiredCustomModifiers
!= null ? requiredCustomModifiers
[i
] : null,
238 optionalCustomModifiers
!= null ? optionalCustomModifiers
[i
] : null);
242 [MonoTODO ("pinned is ignored")]
243 public void AddArgument (Type argument
, bool pinned
)
245 AddArgument (argument
);
248 public void AddArgument (Type argument
, Type
[] requiredCustomModifiers
, Type
[] optionalCustomModifiers
)
250 if (argument
== null)
251 throw new ArgumentNullException ("argument");
253 if (requiredCustomModifiers
!= null)
254 ValidateParameterModifiers ("requiredCustomModifiers", requiredCustomModifiers
);
255 if (optionalCustomModifiers
!= null)
256 ValidateParameterModifiers ("optionalCustomModifiers", optionalCustomModifiers
);
258 int p
= AppendArray (ref arguments
, argument
);
259 if (requiredCustomModifiers
!= null)
260 AppendArrayAt (ref modreqs
, requiredCustomModifiers
, p
);
261 if (optionalCustomModifiers
!= null)
262 AppendArrayAt (ref modopts
, optionalCustomModifiers
, p
);
265 public void AddArgument (Type clsArgument
)
267 if (clsArgument
== null)
268 throw new ArgumentNullException ("clsArgument");
270 AppendArray (ref arguments
, clsArgument
);
273 [MonoTODO("Not implemented")]
274 public void AddSentinel ()
276 throw new NotImplementedException ();
279 static bool CompareOK (Type
[][] one
, Type
[][] two
)
285 } else if (two
== null)
288 if (one
.Length
!= two
.Length
)
291 for (int i
= 0; i
< one
.Length
; i
++){
292 Type
[] tone
= one
[i
];
293 Type
[] ttwo
= two
[i
];
298 } else if (ttwo
== null)
301 if (tone
.Length
!= ttwo
.Length
)
304 for (int j
= 0; j
< tone
.Length
; j
++){
305 Type uone
= tone
[j
];
306 Type utwo
= ttwo
[j
];
312 } else if (utwo
== null)
315 if (!uone
.Equals (utwo
))
322 public override bool Equals (object obj
)
324 SignatureHelper other
= obj
as SignatureHelper
;
328 if (other
.module
!= module
||
329 other
.returnType
!= returnType
||
330 other
.callConv
!= callConv
||
331 other
.unmanagedCallConv
!= unmanagedCallConv
)
334 if (arguments
!= null){
335 if (other
.arguments
== null)
337 if (arguments
.Length
!= other
.arguments
.Length
)
340 for (int i
= 0; i
< arguments
.Length
; i
++)
341 if (!other
.arguments
[i
].Equals (arguments
[i
]))
343 } else if (other
.arguments
!= null)
346 return CompareOK (other
.modreqs
, modreqs
) && CompareOK (other
.modopts
, modopts
);
349 public override int GetHashCode ()
351 // Lame, but easy, and will work, and chances are
352 // you will only need a few of these.
356 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
357 internal extern byte[] get_signature_local ();
359 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
360 internal extern byte[] get_signature_field ();
362 public byte[] GetSignature ()
364 TypeBuilder
.ResolveUserTypes (arguments
);
367 case SignatureHelperType
.HELPER_LOCAL
:
368 return get_signature_local ();
369 case SignatureHelperType
.HELPER_FIELD
:
370 return get_signature_field ();
372 throw new NotImplementedException ();
376 public override string ToString() {
377 return "SignatureHelper";
380 internal static SignatureHelper
GetMethodSigHelper (Module mod
, CallingConventions callingConvention
, CallingConvention unmanagedCallingConvention
, Type returnType
,
383 if (mod
!= null && !(mod
is ModuleBuilder
))
384 throw new ArgumentException ("ModuleBuilder is expected");
386 if (returnType
== null)
387 returnType
= typeof (void);
389 if (returnType
.IsUserType
)
390 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
391 if (parameters
!= null) {
392 for (int i
= 0; i
< parameters
.Length
; ++i
)
393 if (parameters
[i
].IsUserType
)
394 throw new NotSupportedException ("User defined subclasses of System.Type are not yet supported.");
398 SignatureHelper helper
=
399 new SignatureHelper ((ModuleBuilder
)mod
, SignatureHelperType
.HELPER_METHOD
);
400 helper
.returnType
= returnType
;
401 helper
.callConv
= callingConvention
;
402 helper
.unmanagedCallConv
= unmanagedCallingConvention
;
404 if (parameters
!= null) {
405 helper
.arguments
= new Type
[parameters
.Length
];
406 for (int i
= 0; i
< parameters
.Length
; ++i
)
407 helper
.arguments
[i
] = parameters
[i
];
413 void _SignatureHelper
.GetIDsOfNames ([In
] ref Guid riid
, IntPtr rgszNames
, uint cNames
, uint lcid
, IntPtr rgDispId
)
415 throw new NotImplementedException ();
418 void _SignatureHelper
.GetTypeInfo (uint iTInfo
, uint lcid
, IntPtr ppTInfo
)
420 throw new NotImplementedException ();
423 void _SignatureHelper
.GetTypeInfoCount (out uint pcTInfo
)
425 throw new NotImplementedException ();
428 void _SignatureHelper
.Invoke (uint dispIdMember
, [In
] ref Guid riid
, uint lcid
, short wFlags
, IntPtr pDispParams
, IntPtr pVarResult
, IntPtr pExcepInfo
, IntPtr puArgErr
)
430 throw new NotImplementedException ();