Merge pull request #1588 from BrzVlad/feature-aot-wbarrier
[mono.git] / mcs / class / corlib / ReferenceSources / RuntimeType.cs
1 //
2 // RuntimeType.cs
3 //
4 // Authors:
5 //      Marek Safar  <marek.safar@gmail.com>
6 //
7 // Copyright (C) 2015 Xamarin Inc (http://www.xamarin.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Reflection;
30 using System.Runtime.CompilerServices;
31 using System.Threading;
32 using System.Collections.Generic;
33 using System.Runtime.InteropServices;
34 using System.Globalization;
35 #if MONO_COM
36 using System.Reflection.Emit;
37 #endif
38 using System.Diagnostics.Contracts;
39 using System.Security;
40 using System.Runtime.Serialization;
41
42 namespace System
43 {
44         partial class RuntimeType
45         {
46                 internal virtual MonoCMethod GetDefaultConstructor ()
47                 {
48                         // TODO: Requires MonoType
49                         throw new NotSupportedException ();
50                 }
51
52                 string GetDefaultMemberName ()
53                 {
54                         object [] att = GetCustomAttributes (typeof (DefaultMemberAttribute), true);
55                         return att.Length != 0 ? ((DefaultMemberAttribute) att [0]).MemberName : null;
56                 }
57
58                 RuntimeConstructorInfo m_serializationCtor;
59                 internal RuntimeConstructorInfo GetSerializationCtor()
60                 {
61                         if (m_serializationCtor == null) {
62                                 var s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
63
64                                 m_serializationCtor = GetConstructor(
65                                         BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
66                                         null,
67                                         CallingConventions.Any,
68                                         s_SICtorParamTypes,
69                                         null) as RuntimeConstructorInfo;
70                         }
71
72                         return m_serializationCtor;
73                 }
74
75                 internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
76                 {
77                         bool bNeedSecurityCheck = true;
78                         bool bCanBeCached = false;
79                         bool bSecurityCheckOff = false;
80
81                         if (!skipCheckThis)
82                                 CreateInstanceCheckThis();
83
84                         if (!fillCache)
85                                 bSecurityCheckOff = true;
86
87                         return CreateInstanceMono (!publicOnly);
88                 }
89
90                 object CreateInstanceMono (bool nonPublic)
91                 {
92                         var ctor = GetDefaultConstructor ();
93                         if (!nonPublic && ctor != null && !ctor.IsPublic) {
94                                 ctor = null;
95                         }
96
97                         if (ctor == null) {
98                                 Type elementType = this.GetRootElementType();
99                                 if (ReferenceEquals (elementType, typeof (TypedReference)) || ReferenceEquals (elementType, typeof (RuntimeArgumentHandle)))
100                                         throw new NotSupportedException (Environment.GetResourceString ("NotSupported_ContainsStackPtr"));
101
102                                 if (IsValueType)
103                                         return CreateInstanceInternal (this);
104
105                                 throw new MissingMethodException (Locale.GetText ("Default constructor not found for type " + FullName));
106                         }
107
108                         // TODO: .net does more checks in unmanaged land in RuntimeTypeHandle::CreateInstance
109                         if (IsAbstract) {
110                                 throw new MissingMethodException (Locale.GetText ("Cannot create an abstract class '{0}'.", FullName));
111                         }
112
113                         return ctor.InternalInvoke (null, null);
114                 }
115
116                 internal Object CheckValue (Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
117                 {
118                         bool failed = false;
119                         var res = TryConvertToType (value, ref failed);
120                         if (!failed)
121                                 return res;
122
123                         if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
124                                 throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
125
126                         if (binder != null && binder != Type.DefaultBinder)
127                                 return binder.ChangeType (value, this, culture);
128
129                         throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
130                 }
131
132                 object TryConvertToType (object value, ref bool failed)
133                 {
134                         if (IsInstanceOfType (value)) {
135                                 return value;
136                         }
137
138                         if (IsByRef) {
139                                 var elementType = GetElementType ();
140                                 if (value == null || elementType.IsInstanceOfType (value)) {
141                                         return value;
142                                 }
143                         }
144
145                         if (value == null)
146                                 return value;
147
148                         if (IsEnum) {
149                                 var type = Enum.GetUnderlyingType (this);
150                                 if (type == value.GetType ())
151                                         return value;
152                                 var res = IsConvertibleToPrimitiveType (value, this);
153                                 if (res != null)
154                                         return res;
155                         } else if (IsPrimitive) {
156                                 var res = IsConvertibleToPrimitiveType (value, this);
157                                 if (res != null)
158                                         return res;
159                         } else if (IsPointer) {
160                                 var vtype = value.GetType ();
161                                 if (vtype == typeof (IntPtr) || vtype == typeof (UIntPtr))
162                                         return value;
163                         }
164
165                         failed = true;
166                         return null;
167                 }
168
169                 // Binder uses some incompatible conversion rules. For example
170                 // int value cannot be used with decimal parameter but in other
171                 // ways it's more flexible than normal convertor, for example
172                 // long value can be used with int based enum
173                 static object IsConvertibleToPrimitiveType (object value, Type targetType)
174                 {
175                         var type = value.GetType ();
176                         if (type.IsEnum) {
177                                 type = Enum.GetUnderlyingType (type);
178                                 if (type == targetType)
179                                         return value;
180                         }
181
182                         var from = Type.GetTypeCode (type);
183                         var to = Type.GetTypeCode (targetType);
184
185                         switch (to) {
186                                 case TypeCode.Char:
187                                         switch (from) {
188                                                 case TypeCode.Byte:
189                                                         return (Char) (Byte) value;
190                                                 case TypeCode.UInt16:
191                                                         return value;
192                                         }
193                                         break;
194                                 case TypeCode.Int16:
195                                         switch (from) {
196                                                 case TypeCode.Byte:
197                                                         return (Int16) (Byte) value;
198                                                 case TypeCode.SByte:
199                                                         return (Int16) (SByte) value;
200                                         }
201                                         break;
202                                 case TypeCode.UInt16:
203                                         switch (from) {
204                                                 case TypeCode.Byte:
205                                                         return (UInt16) (Byte) value;
206                                                 case TypeCode.Char:
207                                                         return value;
208                                         }
209                                         break;
210                                 case TypeCode.Int32:
211                                         switch (from) {
212                                                 case TypeCode.Byte:
213                                                         return (Int32) (Byte) value;
214                                                 case TypeCode.SByte:
215                                                         return (Int32) (SByte) value;
216                                                 case TypeCode.Char:
217                                                         return (Int32) (Char) value;
218                                                 case TypeCode.Int16:
219                                                         return (Int32) (Int16) value;
220                                                 case TypeCode.UInt16:
221                                                         return (Int32) (UInt16) value;
222                                         }
223                                         break;
224                                 case TypeCode.UInt32:
225                                         switch (from) {
226                                                 case TypeCode.Byte:
227                                                         return (UInt32) (Byte) value;
228                                                 case TypeCode.Char:
229                                                         return (UInt32) (Char) value;
230                                                 case TypeCode.UInt16:
231                                                         return (UInt32) (UInt16) value;
232                                         }
233                                         break;
234                                 case TypeCode.Int64:
235                                         switch (from) {
236                                                 case TypeCode.Byte:
237                                                         return (Int64) (Byte) value;
238                                                 case TypeCode.SByte:
239                                                         return (Int64) (SByte) value;
240                                                 case TypeCode.Int16:
241                                                         return (Int64) (Int16) value;
242                                                 case TypeCode.Char:
243                                                         return (Int64) (Char) value;
244                                                 case TypeCode.UInt16:
245                                                         return (Int64) (UInt16) value;
246                                                 case TypeCode.Int32:
247                                                         return (Int64) (Int32) value;
248                                                 case TypeCode.UInt32:
249                                                         return (Int64) (UInt32) value;
250                                         }
251                                         break;
252                                 case TypeCode.UInt64:
253                                         switch (from) {
254                                                 case TypeCode.Byte:
255                                                         return (UInt64) (Byte) value;
256                                                 case TypeCode.Char:
257                                                         return (UInt64) (Char) value;
258                                                 case TypeCode.UInt16:
259                                                         return (UInt64) (UInt16) value;
260                                                 case TypeCode.UInt32:
261                                                         return (UInt64) (UInt32) value;
262                                         }
263                                         break;
264                                 case TypeCode.Single:
265                                         switch (from) {
266                                                 case TypeCode.Byte:
267                                                         return (Single) (Byte) value;
268                                                 case TypeCode.SByte:
269                                                         return (Single) (SByte) value;
270                                                 case TypeCode.Int16:
271                                                         return (Single) (Int16) value;
272                                                 case TypeCode.Char:
273                                                         return (Single) (Char) value;
274                                                 case TypeCode.UInt16:
275                                                         return (Single) (UInt16) value;
276                                                 case TypeCode.Int32:
277                                                         return (Single) (Int32) value;
278                                                 case TypeCode.UInt32:
279                                                         return (Single) (UInt32) value;
280                                                 case TypeCode.Int64:
281                                                         return (Single) (Int64) value;
282                                                 case TypeCode.UInt64:
283                                                         return (Single) (UInt64) value;
284                                         }
285                                         break;
286                                 case TypeCode.Double:
287                                         switch (from) {
288                                                 case TypeCode.Byte:
289                                                         return (Double) (Byte) value;
290                                                 case TypeCode.SByte:
291                                                         return (Double) (SByte) value;
292                                                 case TypeCode.Char:
293                                                         return (Double) (Char) value;
294                                                 case TypeCode.Int16:
295                                                         return (Double) (Int16) value;
296                                                 case TypeCode.UInt16:
297                                                         return (Double) (UInt16) value;
298                                                 case TypeCode.Int32:
299                                                         return (Double) (Int32) value;
300                                                 case TypeCode.UInt32:
301                                                         return (Double) (UInt32) value;
302                                                 case TypeCode.Int64:
303                                                         return (Double) (Int64) value;
304                                                 case TypeCode.UInt64:
305                                                         return (Double) (UInt64) value;
306                                                 case TypeCode.Single:
307                                                         return (Double) (Single) value;
308                                         }
309                                         break;
310                         }
311
312                         // Everything else is rejected
313                         return null;
314                 }
315
316                 string GetCachedName (TypeNameKind kind)
317                 {
318                         switch (kind) {
319                         case TypeNameKind.SerializationName:
320                                 return ToString ();
321                         default:
322                                 throw new NotImplementedException ();
323                         }
324                 }
325
326                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
327                 extern Type make_array_type (int rank);
328
329                 public override Type MakeArrayType ()
330                 {
331                         return make_array_type (0);
332                 }
333
334                 public override Type MakeArrayType (int rank)
335                 {
336                         if (rank < 1 || rank > 255)
337                                 throw new IndexOutOfRangeException ();
338                         return make_array_type (rank);
339                 }
340
341                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
342                 extern Type make_byref_type ();
343
344                 public override Type MakeByRefType ()
345                 {
346                         if (IsByRef)
347                                 throw new TypeLoadException ("Can not call MakeByRefType on a ByRef type");
348                         return make_byref_type ();
349                 }
350
351                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
352                 static extern Type MakePointerType (Type type);
353
354                 public override Type MakePointerType ()
355                 {
356                         return MakePointerType (this);
357                 }
358
359                 public override StructLayoutAttribute StructLayoutAttribute {
360                         get {
361                                 return GetStructLayoutAttribute ();
362                         }
363                 }
364
365                 public override bool ContainsGenericParameters {
366                         get {
367                                 if (IsGenericParameter)
368                                         return true;
369
370                                 if (IsGenericType) {
371                                         foreach (Type arg in GetGenericArguments ())
372                                                 if (arg.ContainsGenericParameters)
373                                                         return true;
374                                 }
375
376                                 if (HasElementType)
377                                         return GetElementType ().ContainsGenericParameters;
378
379                                 return false;
380                         }
381                 }
382
383                 public override Type[] GetGenericParameterConstraints()
384                 {
385                         if (!IsGenericParameter)
386                                 throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
387                         Contract.EndContractBlock();
388
389                         Type[] constraints = GetGenericParameterConstraints_impl ();
390
391                         if (constraints == null)
392                                 constraints = EmptyArray<Type>.Value;
393
394                         return constraints;
395                 }
396
397                 public override Type MakeGenericType (params Type[] typeArguments)
398                 {
399                         if (IsUserType)
400                                 throw new NotSupportedException ();
401                         if (!IsGenericTypeDefinition)
402                                 throw new InvalidOperationException ("not a generic type definition");
403                         if (typeArguments == null)
404                                 throw new ArgumentNullException ("typeArguments");
405                         if (GetGenericArguments().Length != typeArguments.Length)
406                                 throw new ArgumentException (String.Format ("The type or method has {0} generic parameter(s) but {1} generic argument(s) where provided. A generic argument must be provided for each generic parameter.", GetGenericArguments ().Length, typeArguments.Length), "typeArguments");
407
408                         bool hasUserType = false;
409
410                         Type[] systemTypes = new Type[typeArguments.Length];
411                         for (int i = 0; i < typeArguments.Length; ++i) {
412                                 Type t = typeArguments [i];
413                                 if (t == null)
414                                         throw new ArgumentNullException ("typeArguments");
415
416                                 if (!(t is MonoType))
417                                         hasUserType = true;
418                                 systemTypes [i] = t;
419                         }
420
421                         if (hasUserType) {
422 #if FULL_AOT_RUNTIME
423                                 throw new NotSupportedException ("User types are not supported under full aot");
424 #else
425                                 return new MonoGenericClass (this, typeArguments);
426 #endif
427                         }
428
429                         Type res = MakeGenericType (this, systemTypes);
430                         if (res == null)
431                                 throw new TypeLoadException ();
432                         return res;
433                 }
434
435                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
436                 static extern Type MakeGenericType (Type gt, Type [] types);
437
438                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
439                 internal extern RuntimeMethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type);
440
441                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
442                 extern RuntimePropertyInfo[] GetPropertiesByName (string name, BindingFlags bindingAttr, bool icase, Type reflected_type);              
443
444                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
445                 extern RuntimeConstructorInfo[] GetConstructors_internal (BindingFlags bindingAttr, Type reflected_type);
446
447                 public override InterfaceMapping GetInterfaceMap (Type ifaceType)
448                 {
449                         if (IsGenericParameter)
450                                 throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
451                 
452                         if ((object)ifaceType == null)
453                                 throw new ArgumentNullException("ifaceType");
454                         Contract.EndContractBlock();
455
456                         RuntimeType ifaceRtType = ifaceType as RuntimeType;
457
458                         if (ifaceRtType == null)
459                                 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
460
461                         InterfaceMapping res;
462                         if (!ifaceType.IsInterface)
463                                 throw new ArgumentException (Locale.GetText ("Argument must be an interface."), "ifaceType");
464                         if (IsInterface)
465                                 throw new ArgumentException ("'this' type cannot be an interface itself");
466                         res.TargetType = this;
467                         res.InterfaceType = ifaceType;
468                         GetInterfaceMapData (this, ifaceType, out res.TargetMethods, out res.InterfaceMethods);
469                         if (res.TargetMethods == null)
470                                 throw new ArgumentException (Locale.GetText ("Interface not found"), "ifaceType");
471
472                         return res;
473                 }
474
475                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
476                 static extern void GetInterfaceMapData (Type t, Type iface, out MethodInfo[] targets, out MethodInfo[] methods);                
477
478                 public override Guid GUID {
479                         get {
480                                 object[] att = GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true);
481                                 if (att.Length == 0)
482                                         return Guid.Empty;
483                                 return new Guid(((System.Runtime.InteropServices.GuidAttribute)att[0]).Value);
484                         }
485                 }
486
487                 StructLayoutAttribute GetStructLayoutAttribute ()
488                 {
489                         LayoutKind kind;
490
491                         if (IsLayoutSequential)
492                                 kind = LayoutKind.Sequential;
493                         else if (IsExplicitLayout)
494                                 kind = LayoutKind.Explicit;
495                         else
496                                 kind = LayoutKind.Auto;
497
498                         StructLayoutAttribute attr = new StructLayoutAttribute (kind);
499
500                         if (IsUnicodeClass)
501                                 attr.CharSet = CharSet.Unicode;
502                         else if (IsAnsiClass)
503                                 attr.CharSet = CharSet.Ansi;
504                         else
505                                 attr.CharSet = CharSet.Auto;
506
507                         if (kind != LayoutKind.Auto) {
508                                 int packing;
509                                 GetPacking (out packing, out attr.Size);
510                                 // 0 means no data provided, we end up with default value
511                                 if (packing != 0)
512                                         attr.Pack = packing;
513                         }
514
515                         return attr;
516                 }
517
518                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
519                 extern void GetPacking (out int packing, out int size);
520
521 #if MONO_COM
522                 private static Dictionary<Guid, Type> clsid_types;
523                 private static AssemblyBuilder clsid_assemblybuilder;
524 #endif
525
526                 internal static Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError)
527                 {
528 #if MONO_COM
529                         Type result;
530
531                         if (clsid_types == null)
532                         {
533                                 Dictionary<Guid, Type> new_clsid_types = new Dictionary<Guid, Type> ();
534                                 Interlocked.CompareExchange<Dictionary<Guid, Type>>(
535                                         ref clsid_types, new_clsid_types, null);
536                         }
537
538                         lock (clsid_types) {
539                                 if (clsid_types.TryGetValue(clsid, out result))
540                                         return result;
541
542                                 if (clsid_assemblybuilder == null)
543                                 {
544                                         AssemblyName assemblyname = new AssemblyName ();
545                                         assemblyname.Name = "GetTypeFromCLSIDDummyAssembly";
546                                         clsid_assemblybuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (
547                                                 assemblyname, AssemblyBuilderAccess.Run);
548                                 }
549                                 ModuleBuilder modulebuilder = clsid_assemblybuilder.DefineDynamicModule (
550                                         clsid.ToString ());
551
552                                 TypeBuilder typebuilder = modulebuilder.DefineType ("System.__ComObject",
553                                         TypeAttributes.Public | TypeAttributes.Class, typeof(System.__ComObject));
554
555                                 Type[] guidattrtypes = new Type[] { typeof(string) };
556
557                                 CustomAttributeBuilder customattr = new CustomAttributeBuilder (
558                                         typeof(GuidAttribute).GetConstructor (guidattrtypes),
559                                         new object[] { clsid.ToString () });
560
561                                 typebuilder.SetCustomAttribute (customattr);
562
563                                 customattr = new CustomAttributeBuilder (
564                                         typeof(ComImportAttribute).GetConstructor (EmptyTypes),
565                                         new object[0] {});
566
567                                 typebuilder.SetCustomAttribute (customattr);
568
569                                 result = typebuilder.CreateType ();
570
571                                 clsid_types.Add(clsid, result);
572
573                                 return result;
574                         }
575 #else
576                         throw new NotImplementedException ("Unmanaged activation removed");
577 #endif
578                 }
579
580                 protected override TypeCode GetTypeCodeImpl ()
581                 {
582                         return GetTypeCodeImplInternal (this);
583                 }
584
585                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
586                 extern static TypeCode GetTypeCodeImplInternal (Type type);             
587
588                 internal static Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError)
589                 {
590                         throw new NotImplementedException ("Unmanaged activation is not supported");
591                 }
592
593                 public override string ToString()
594                 {
595                         return getFullName (false, false);
596                 }
597
598                 bool IsGenericCOMObjectImpl ()
599                 {
600                         return false;
601                 }
602
603                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
604                 static extern object CreateInstanceInternal (Type type);
605
606                 public extern override MethodBase DeclaringMethod {
607                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
608                         get;
609                 }               
610                 
611                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
612                 internal extern string getFullName(bool full_name, bool assembly_qualified);
613
614                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
615                 public extern override Type [] GetGenericArguments ();
616
617                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
618                 extern GenericParameterAttributes GetGenericParameterAttributes ();
619
620                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
621                 extern Type[] GetGenericParameterConstraints_impl ();
622
623                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
624                 extern int GetGenericParameterPosition ();
625
626                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
627                 extern RuntimeEventInfo[] GetEvents_internal (string name, BindingFlags bindingAttr, Type reflected_type);
628
629                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
630                 extern RuntimeFieldInfo[] GetFields_internal (string name, BindingFlags bindingAttr, Type reflected_type);
631
632                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
633                 public extern override Type[] GetInterfaces();
634
635                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
636                 extern RuntimeType[] GetNestedTypes_internal (string name, BindingFlags bindingAttr);           
637
638                 public override string AssemblyQualifiedName {
639                         get {
640                                 return getFullName (true, true);
641                         }
642                 }
643
644                 public extern override Type DeclaringType {
645                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
646                         get;
647                 }
648
649                 public override string FullName {
650                         get {
651                                 throw new NotImplementedException ();
652                         }
653                 }
654
655                 public extern override string Name {
656                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
657                         get;
658                 }
659
660                 public extern override string Namespace {
661                         [MethodImplAttribute(MethodImplOptions.InternalCall)]
662                         get;
663                 }
664
665                 //seclevel { transparent = 0, safe-critical = 1, critical = 2}
666                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
667                 public extern int get_core_clr_security_level ();
668
669                 public override bool IsSecurityTransparent {
670                         get { return get_core_clr_security_level () == 0; }
671                 }
672
673                 public override bool IsSecurityCritical {
674                         get { return get_core_clr_security_level () > 0; }
675                 }
676
677                 public override bool IsSecuritySafeCritical {
678                         get { return get_core_clr_security_level () == 1; }
679                 }               
680         }
681 }