1 /* 2 Copyright (C) 2008-2011 Jeroen Frijters 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely, subject to the following restrictions: 11 12 1. The origin of this software must not be misrepresented; you must not 13 claim that you wrote the original software. If you use this software 14 in a product, an acknowledgment in the product documentation would be 15 appreciated but is not required. 16 2. Altered source versions must be plainly marked as such, and must not be 17 misrepresented as being the original software. 18 3. This notice may not be removed or altered from any source distribution. 19 20 Jeroen Frijters 21 jeroen@frijters.net 22 23 */ 24 using System; 25 using System.Collections.Generic; 26 using System.Diagnostics; 27 using System.Runtime.InteropServices; 28 using IKVM.Reflection.Impl; 29 using IKVM.Reflection.Metadata; 30 using IKVM.Reflection.Writer; 31 32 namespace IKVM.Reflection.Emit 33 { 34 public sealed class GenericTypeParameterBuilder : TypeInfo 35 { 36 private readonly string name; 37 private readonly TypeBuilder type; 38 private readonly MethodBuilder method; 39 private readonly int paramPseudoIndex; 40 private readonly int position; 41 private int typeToken; 42 private Type baseType; 43 private GenericParameterAttributes attr; 44 GenericTypeParameterBuilder(string name, TypeBuilder type, int position)45 internal GenericTypeParameterBuilder(string name, TypeBuilder type, int position) 46 : this(name, type, null, position, Signature.ELEMENT_TYPE_VAR) 47 { 48 } 49 GenericTypeParameterBuilder(string name, MethodBuilder method, int position)50 internal GenericTypeParameterBuilder(string name, MethodBuilder method, int position) 51 : this(name, null, method, position, Signature.ELEMENT_TYPE_MVAR) 52 { 53 } 54 GenericTypeParameterBuilder(string name, TypeBuilder type, MethodBuilder method, int position, byte sigElementType)55 private GenericTypeParameterBuilder(string name, TypeBuilder type, MethodBuilder method, int position, byte sigElementType) 56 : base(sigElementType) 57 { 58 this.name = name; 59 this.type = type; 60 this.method = method; 61 this.position = position; 62 GenericParamTable.Record rec = new GenericParamTable.Record(); 63 rec.Number = (short)position; 64 rec.Flags = 0; 65 rec.Owner = type != null ? type.MetadataToken : method.MetadataToken; 66 rec.Name = this.ModuleBuilder.Strings.Add(name); 67 this.paramPseudoIndex = this.ModuleBuilder.GenericParam.AddRecord(rec); 68 } 69 70 public override string AssemblyQualifiedName 71 { 72 get { return null; } 73 } 74 75 public override bool IsValueType 76 { 77 get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; } 78 } 79 80 public override Type BaseType 81 { 82 get { return baseType; } 83 } 84 __GetDeclaredInterfaces()85 public override Type[] __GetDeclaredInterfaces() 86 { 87 throw new NotImplementedException(); 88 } 89 90 public override TypeAttributes Attributes 91 { 92 get { return TypeAttributes.Public; } 93 } 94 95 public override string Namespace 96 { 97 get { return DeclaringType.Namespace; } 98 } 99 100 public override string Name 101 { 102 get { return name; } 103 } 104 105 public override string FullName 106 { 107 get { return null; } 108 } 109 ToString()110 public override string ToString() 111 { 112 return this.Name; 113 } 114 115 private ModuleBuilder ModuleBuilder 116 { 117 get { return type != null ? type.ModuleBuilder : method.ModuleBuilder; } 118 } 119 120 public override Module Module 121 { 122 get { return ModuleBuilder; } 123 } 124 125 public override int GenericParameterPosition 126 { 127 get { return position; } 128 } 129 130 public override Type DeclaringType 131 { 132 get { return type; } 133 } 134 135 public override MethodBase DeclaringMethod 136 { 137 get { return method; } 138 } 139 GetGenericParameterConstraints()140 public override Type[] GetGenericParameterConstraints() 141 { 142 throw new NotImplementedException(); 143 } 144 __GetGenericParameterConstraintCustomModifiers()145 public override CustomModifiers[] __GetGenericParameterConstraintCustomModifiers() 146 { 147 throw new NotImplementedException(); 148 } 149 150 public override GenericParameterAttributes GenericParameterAttributes 151 { 152 get 153 { 154 CheckBaked(); 155 return attr; 156 } 157 } 158 CheckBaked()159 internal override void CheckBaked() 160 { 161 if (type != null) 162 { 163 type.CheckBaked(); 164 } 165 else 166 { 167 method.CheckBaked(); 168 } 169 } 170 AddConstraint(Type type)171 private void AddConstraint(Type type) 172 { 173 GenericParamConstraintTable.Record rec = new GenericParamConstraintTable.Record(); 174 rec.Owner = paramPseudoIndex; 175 rec.Constraint = this.ModuleBuilder.GetTypeTokenForMemberRef(type); 176 this.ModuleBuilder.GenericParamConstraint.AddRecord(rec); 177 } 178 SetBaseTypeConstraint(Type baseTypeConstraint)179 public void SetBaseTypeConstraint(Type baseTypeConstraint) 180 { 181 this.baseType = baseTypeConstraint; 182 AddConstraint(baseTypeConstraint); 183 } 184 SetInterfaceConstraints(params Type[] interfaceConstraints)185 public void SetInterfaceConstraints(params Type[] interfaceConstraints) 186 { 187 foreach (Type type in interfaceConstraints) 188 { 189 AddConstraint(type); 190 } 191 } 192 SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes)193 public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes) 194 { 195 this.attr = genericParameterAttributes; 196 // for now we'll back patch the table 197 this.ModuleBuilder.GenericParam.PatchAttribute(paramPseudoIndex, genericParameterAttributes); 198 } 199 SetCustomAttribute(CustomAttributeBuilder customBuilder)200 public void SetCustomAttribute(CustomAttributeBuilder customBuilder) 201 { 202 this.ModuleBuilder.SetCustomAttribute((GenericParamTable.Index << 24) | paramPseudoIndex, customBuilder); 203 } 204 SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)205 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) 206 { 207 SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); 208 } 209 210 public override int MetadataToken 211 { 212 get 213 { 214 CheckBaked(); 215 return (GenericParamTable.Index << 24) | paramPseudoIndex; 216 } 217 } 218 GetModuleBuilderToken()219 internal override int GetModuleBuilderToken() 220 { 221 if (typeToken == 0) 222 { 223 ByteBuffer spec = new ByteBuffer(5); 224 Signature.WriteTypeSpec(this.ModuleBuilder, spec, this); 225 typeToken = 0x1B000000 | this.ModuleBuilder.TypeSpec.AddRecord(this.ModuleBuilder.Blobs.Add(spec)); 226 } 227 return typeToken; 228 } 229 BindTypeParameters(IGenericBinder binder)230 internal override Type BindTypeParameters(IGenericBinder binder) 231 { 232 if (type != null) 233 { 234 return binder.BindTypeParameter(this); 235 } 236 else 237 { 238 return binder.BindMethodParameter(this); 239 } 240 } 241 GetCurrentToken()242 internal override int GetCurrentToken() 243 { 244 if (this.ModuleBuilder.IsSaved) 245 { 246 return (GenericParamTable.Index << 24) | this.Module.GenericParam.GetIndexFixup()[paramPseudoIndex - 1] + 1; 247 } 248 else 249 { 250 return (GenericParamTable.Index << 24) | paramPseudoIndex; 251 } 252 } 253 254 internal override bool IsBaked 255 { 256 get { return ((MemberInfo)type ?? method).IsBaked; } 257 } 258 } 259 260 public sealed class TypeBuilder : TypeInfo, ITypeOwner 261 { 262 public const int UnspecifiedTypeSize = 0; 263 private readonly ITypeOwner owner; 264 private readonly int token; 265 private int extends; 266 private Type lazyBaseType; // (lazyBaseType == null && attribs & TypeAttributes.Interface) == 0) => BaseType == System.Object 267 private readonly int typeName; 268 private readonly int typeNameSpace; 269 private readonly string ns; 270 private readonly string name; 271 private readonly List<MethodBuilder> methods = new List<MethodBuilder>(); 272 private readonly List<FieldBuilder> fields = new List<FieldBuilder>(); 273 private List<PropertyBuilder> properties; 274 private List<EventBuilder> events; 275 private TypeAttributes attribs; 276 private GenericTypeParameterBuilder[] gtpb; 277 private List<CustomAttributeBuilder> declarativeSecurity; 278 private List<Type> interfaces; 279 private int size; 280 private short pack; 281 private bool hasLayout; 282 TypeBuilder(ITypeOwner owner, string ns, string name)283 internal TypeBuilder(ITypeOwner owner, string ns, string name) 284 { 285 this.owner = owner; 286 this.token = this.ModuleBuilder.TypeDef.AllocToken(); 287 this.ns = ns; 288 this.name = name; 289 this.typeNameSpace = ns == null ? 0 : this.ModuleBuilder.Strings.Add(ns); 290 this.typeName = this.ModuleBuilder.Strings.Add(name); 291 MarkKnownType(ns, name); 292 } 293 DefineDefaultConstructor(MethodAttributes attributes)294 public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes) 295 { 296 ConstructorBuilder cb = DefineConstructor(attributes, CallingConventions.Standard, Type.EmptyTypes); 297 ILGenerator ilgen = cb.GetILGenerator(); 298 ilgen.Emit(OpCodes.Ldarg_0); 299 ilgen.Emit(OpCodes.Call, BaseType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); 300 ilgen.Emit(OpCodes.Ret); 301 return cb; 302 } 303 DefineConstructor(MethodAttributes attribs, CallingConventions callConv, Type[] parameterTypes)304 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callConv, Type[] parameterTypes) 305 { 306 return DefineConstructor(attribs, callConv, parameterTypes, null, null); 307 } 308 DefineConstructor(MethodAttributes attribs, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)309 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) 310 { 311 attribs |= MethodAttributes.RTSpecialName | MethodAttributes.SpecialName; 312 string name = (attribs & MethodAttributes.Static) == 0 ? ConstructorInfo.ConstructorName : ConstructorInfo.TypeConstructorName; 313 MethodBuilder mb = DefineMethod(name, attribs, callingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); 314 return new ConstructorBuilder(mb); 315 } 316 DefineTypeInitializer()317 public ConstructorBuilder DefineTypeInitializer() 318 { 319 MethodBuilder mb = DefineMethod(ConstructorInfo.TypeConstructorName, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, null, Type.EmptyTypes); 320 return new ConstructorBuilder(mb); 321 } 322 CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention)323 private MethodBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention) 324 { 325 this.ModuleBuilder.MethodDef.AddVirtualRecord(); 326 MethodBuilder mb = new MethodBuilder(this, name, attributes, callingConvention); 327 methods.Add(mb); 328 return mb; 329 } 330 DefineMethod(string name, MethodAttributes attribs)331 public MethodBuilder DefineMethod(string name, MethodAttributes attribs) 332 { 333 return DefineMethod(name, attribs, CallingConventions.Standard); 334 } 335 DefineMethod(string name, MethodAttributes attribs, CallingConventions callingConvention)336 public MethodBuilder DefineMethod(string name, MethodAttributes attribs, CallingConventions callingConvention) 337 { 338 return CreateMethodBuilder(name, attribs, callingConvention); 339 } 340 DefineMethod(string name, MethodAttributes attribs, Type returnType, Type[] parameterTypes)341 public MethodBuilder DefineMethod(string name, MethodAttributes attribs, Type returnType, Type[] parameterTypes) 342 { 343 return DefineMethod(name, attribs, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null); 344 } 345 DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)346 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) 347 { 348 return DefineMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); 349 } 350 DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)351 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) 352 { 353 MethodBuilder mb = CreateMethodBuilder(name, attributes, callingConvention); 354 mb.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); 355 return mb; 356 } 357 DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)358 public MethodBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) 359 { 360 return DefinePInvokeMethod(name, dllName, null, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet); 361 } 362 DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)363 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) 364 { 365 return DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet); 366 } 367 DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, CharSet nativeCharSet)368 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, 369 Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, 370 Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, 371 CallingConvention nativeCallConv, CharSet nativeCharSet) 372 { 373 MethodBuilder mb = DefineMethod(name, attributes | MethodAttributes.PinvokeImpl, callingConvention, 374 returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, 375 parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); 376 mb.SetDllImportPseudoCustomAttribute(dllName, entryName, nativeCallConv, nativeCharSet, null, null, null, null, null); 377 return mb; 378 } 379 DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)380 public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) 381 { 382 MethodImplTable.Record rec = new MethodImplTable.Record(); 383 rec.Class = token; 384 rec.MethodBody = this.ModuleBuilder.GetMethodToken(methodInfoBody).Token; 385 rec.MethodDeclaration = this.ModuleBuilder.GetMethodTokenWinRT(methodInfoDeclaration); 386 this.ModuleBuilder.MethodImpl.AddRecord(rec); 387 } 388 DefineField(string name, Type fieldType, FieldAttributes attribs)389 public FieldBuilder DefineField(string name, Type fieldType, FieldAttributes attribs) 390 { 391 return DefineField(name, fieldType, null, null, attribs); 392 } 393 DefineField(string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)394 public FieldBuilder DefineField(string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes) 395 { 396 return __DefineField(fieldName, type, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers), attributes); 397 } 398 __DefineField(string fieldName, Type type, CustomModifiers customModifiers, FieldAttributes attributes)399 public FieldBuilder __DefineField(string fieldName, Type type, CustomModifiers customModifiers, FieldAttributes attributes) 400 { 401 FieldBuilder fb = new FieldBuilder(this, fieldName, type, customModifiers, attributes); 402 fields.Add(fb); 403 return fb; 404 } 405 DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)406 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) 407 { 408 return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null); 409 } 410 DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)411 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) 412 { 413 return DefineProperty(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); 414 } 415 DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)416 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, 417 Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) 418 { 419 return DefinePropertyImpl(name, attributes, CallingConventions.Standard, true, returnType, parameterTypes, 420 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes))); 421 } 422 DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)423 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, 424 Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, 425 Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) 426 { 427 return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes, 428 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes))); 429 } 430 __DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)431 public PropertyBuilder __DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention, 432 Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers) 433 { 434 return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes, 435 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes))); 436 } 437 DefinePropertyImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, bool patchCallingConvention, Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)438 private PropertyBuilder DefinePropertyImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, bool patchCallingConvention, 439 Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers) 440 { 441 if (properties == null) 442 { 443 properties = new List<PropertyBuilder>(); 444 } 445 PropertySignature sig = PropertySignature.Create(callingConvention, returnType, parameterTypes, customModifiers); 446 PropertyBuilder pb = new PropertyBuilder(this, name, attributes, sig, patchCallingConvention); 447 properties.Add(pb); 448 return pb; 449 } 450 DefineEvent(string name, EventAttributes attributes, Type eventtype)451 public EventBuilder DefineEvent(string name, EventAttributes attributes, Type eventtype) 452 { 453 if (events == null) 454 { 455 events = new List<EventBuilder>(); 456 } 457 EventBuilder eb = new EventBuilder(this, name, attributes, eventtype); 458 events.Add(eb); 459 return eb; 460 } 461 DefineNestedType(string name)462 public TypeBuilder DefineNestedType(string name) 463 { 464 return DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPrivate); 465 } 466 DefineNestedType(string name, TypeAttributes attribs)467 public TypeBuilder DefineNestedType(string name, TypeAttributes attribs) 468 { 469 return DefineNestedType(name, attribs, null); 470 } 471 DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces)472 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces) 473 { 474 TypeBuilder tb = DefineNestedType(name, attr, parent); 475 if (interfaces != null) 476 { 477 foreach (Type iface in interfaces) 478 { 479 tb.AddInterfaceImplementation(iface); 480 } 481 } 482 return tb; 483 } 484 DefineNestedType(string name, TypeAttributes attr, Type parent)485 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent) 486 { 487 return DefineNestedType(name, attr, parent, 0); 488 } 489 DefineNestedType(string name, TypeAttributes attr, Type parent, int typeSize)490 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, int typeSize) 491 { 492 return DefineNestedType(name, attr, parent, PackingSize.Unspecified, typeSize); 493 } 494 DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize)495 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize) 496 { 497 return DefineNestedType(name, attr, parent, packSize, 0); 498 } 499 DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize)500 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize) 501 { 502 string ns = null; 503 int lastdot = name.LastIndexOf('.'); 504 if (lastdot > 0) 505 { 506 ns = name.Substring(0, lastdot); 507 name = name.Substring(lastdot + 1); 508 } 509 TypeBuilder typeBuilder = __DefineNestedType(ns, name); 510 typeBuilder.__SetAttributes(attr); 511 typeBuilder.SetParent(parent); 512 if (packSize != PackingSize.Unspecified || typeSize != 0) 513 { 514 typeBuilder.__SetLayout((int)packSize, typeSize); 515 } 516 return typeBuilder; 517 } 518 __DefineNestedType(string ns, string name)519 public TypeBuilder __DefineNestedType(string ns, string name) 520 { 521 this.typeFlags |= TypeFlags.HasNestedTypes; 522 TypeBuilder typeBuilder = this.ModuleBuilder.DefineType(this, ns, name); 523 NestedClassTable.Record rec = new NestedClassTable.Record(); 524 rec.NestedClass = typeBuilder.MetadataToken; 525 rec.EnclosingClass = this.MetadataToken; 526 this.ModuleBuilder.NestedClass.AddRecord(rec); 527 return typeBuilder; 528 } 529 SetParent(Type parent)530 public void SetParent(Type parent) 531 { 532 lazyBaseType = parent; 533 } 534 AddInterfaceImplementation(Type interfaceType)535 public void AddInterfaceImplementation(Type interfaceType) 536 { 537 if (interfaces == null) 538 { 539 interfaces = new List<Type>(); 540 } 541 interfaces.Add(interfaceType); 542 } 543 __SetInterfaceImplementationCustomAttribute(Type interfaceType, CustomAttributeBuilder cab)544 public void __SetInterfaceImplementationCustomAttribute(Type interfaceType, CustomAttributeBuilder cab) 545 { 546 this.ModuleBuilder.SetInterfaceImplementationCustomAttribute(this, interfaceType, cab); 547 } 548 549 public int Size 550 { 551 get { return size; } 552 } 553 554 public PackingSize PackingSize 555 { 556 get { return (PackingSize)pack; } 557 } 558 __GetLayout(out int packingSize, out int typeSize)559 public override bool __GetLayout(out int packingSize, out int typeSize) 560 { 561 packingSize = this.pack; 562 typeSize = this.size; 563 return hasLayout; 564 } 565 __SetLayout(int packingSize, int typesize)566 public void __SetLayout(int packingSize, int typesize) 567 { 568 this.pack = (short)packingSize; 569 this.size = typesize; 570 this.hasLayout = pack != 0 || size != 0; 571 } 572 SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder)573 private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder) 574 { 575 object val = customBuilder.GetConstructorArgument(0); 576 LayoutKind layout; 577 if (val is short) 578 { 579 layout = (LayoutKind)(short)val; 580 } 581 else 582 { 583 layout = (LayoutKind)val; 584 } 585 pack = (short)((int?)customBuilder.GetFieldValue("Pack") ?? 0); 586 size = (int?)customBuilder.GetFieldValue("Size") ?? 0; 587 CharSet charSet = customBuilder.GetFieldValue<CharSet>("CharSet") ?? CharSet.None; 588 attribs &= ~TypeAttributes.LayoutMask; 589 switch (layout) 590 { 591 case LayoutKind.Auto: 592 attribs |= TypeAttributes.AutoLayout; 593 break; 594 case LayoutKind.Explicit: 595 attribs |= TypeAttributes.ExplicitLayout; 596 break; 597 case LayoutKind.Sequential: 598 attribs |= TypeAttributes.SequentialLayout; 599 break; 600 } 601 attribs &= ~TypeAttributes.StringFormatMask; 602 switch (charSet) 603 { 604 case CharSet.None: 605 case CharSet.Ansi: 606 attribs |= TypeAttributes.AnsiClass; 607 break; 608 case CharSet.Auto: 609 attribs |= TypeAttributes.AutoClass; 610 break; 611 case CharSet.Unicode: 612 attribs |= TypeAttributes.UnicodeClass; 613 break; 614 } 615 hasLayout = pack != 0 || size != 0; 616 } 617 SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)618 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) 619 { 620 SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute)); 621 } 622 SetCustomAttribute(CustomAttributeBuilder customBuilder)623 public void SetCustomAttribute(CustomAttributeBuilder customBuilder) 624 { 625 switch (customBuilder.KnownCA) 626 { 627 case KnownCA.StructLayoutAttribute: 628 SetStructLayoutPseudoCustomAttribute(customBuilder.DecodeBlob(this.Assembly)); 629 break; 630 case KnownCA.SerializableAttribute: 631 attribs |= TypeAttributes.Serializable; 632 break; 633 case KnownCA.ComImportAttribute: 634 attribs |= TypeAttributes.Import; 635 break; 636 case KnownCA.SpecialNameAttribute: 637 attribs |= TypeAttributes.SpecialName; 638 break; 639 case KnownCA.SuppressUnmanagedCodeSecurityAttribute: 640 attribs |= TypeAttributes.HasSecurity; 641 goto default; 642 default: 643 this.ModuleBuilder.SetCustomAttribute(token, customBuilder); 644 break; 645 } 646 } 647 __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)648 public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder) 649 { 650 attribs |= TypeAttributes.HasSecurity; 651 if (declarativeSecurity == null) 652 { 653 declarativeSecurity = new List<CustomAttributeBuilder>(); 654 } 655 declarativeSecurity.Add(customBuilder); 656 } 657 658 #if !CORECLR AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)659 public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet) 660 { 661 this.ModuleBuilder.AddDeclarativeSecurity(token, securityAction, permissionSet); 662 this.attribs |= TypeAttributes.HasSecurity; 663 } 664 #endif 665 DefineGenericParameters(params string[] names)666 public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) 667 { 668 typeFlags |= TypeFlags.IsGenericTypeDefinition; 669 gtpb = new GenericTypeParameterBuilder[names.Length]; 670 for (int i = 0; i < names.Length; i++) 671 { 672 gtpb[i] = new GenericTypeParameterBuilder(names[i], this, i); 673 } 674 return (GenericTypeParameterBuilder[])gtpb.Clone(); 675 } 676 GetGenericArguments()677 public override Type[] GetGenericArguments() 678 { 679 return Util.Copy(gtpb); 680 } 681 __GetGenericArgumentsCustomModifiers()682 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() 683 { 684 return gtpb == null ? Empty<CustomModifiers>.Array : new CustomModifiers[gtpb.Length]; 685 } 686 GetGenericTypeArgument(int index)687 internal override Type GetGenericTypeArgument(int index) 688 { 689 return gtpb[index]; 690 } 691 692 public override bool ContainsGenericParameters 693 { 694 get { return gtpb != null; } 695 } 696 GetGenericTypeDefinition()697 public override Type GetGenericTypeDefinition() 698 { 699 return this; 700 } 701 CreateTypeInfo()702 public TypeInfo CreateTypeInfo() 703 { 704 if ((typeFlags & TypeFlags.Baked) != 0) 705 { 706 // .NET allows multiple invocations (subsequent invocations return the same baked type) 707 throw new NotImplementedException(); 708 } 709 typeFlags |= TypeFlags.Baked; 710 if (hasLayout) 711 { 712 ClassLayoutTable.Record rec = new ClassLayoutTable.Record(); 713 rec.PackingSize = pack; 714 rec.ClassSize = size; 715 rec.Parent = token; 716 this.ModuleBuilder.ClassLayout.AddRecord(rec); 717 } 718 bool hasConstructor = false; 719 foreach (MethodBuilder mb in methods) 720 { 721 hasConstructor |= mb.IsSpecialName && mb.Name == ConstructorInfo.ConstructorName; 722 mb.Bake(); 723 } 724 if (!hasConstructor && !IsModulePseudoType && !IsInterface && !IsValueType && !(IsAbstract && IsSealed) && Universe.AutomaticallyProvideDefaultConstructor) 725 { 726 ((MethodBuilder)DefineDefaultConstructor(MethodAttributes.Public).GetMethodInfo()).Bake(); 727 } 728 if (declarativeSecurity != null) 729 { 730 this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity); 731 } 732 if (!IsModulePseudoType) 733 { 734 Type baseType = this.BaseType; 735 if (baseType != null) 736 { 737 extends = this.ModuleBuilder.GetTypeToken(baseType).Token; 738 } 739 } 740 if (interfaces != null) 741 { 742 foreach (Type interfaceType in interfaces) 743 { 744 InterfaceImplTable.Record rec = new InterfaceImplTable.Record(); 745 rec.Class = token; 746 rec.Interface = this.ModuleBuilder.GetTypeToken(interfaceType).Token; 747 this.ModuleBuilder.InterfaceImpl.AddRecord(rec); 748 } 749 } 750 return new BakedType(this); 751 } 752 CreateType()753 public Type CreateType() 754 { 755 return CreateTypeInfo(); 756 } 757 PopulatePropertyAndEventTables()758 internal void PopulatePropertyAndEventTables() 759 { 760 if (properties != null) 761 { 762 PropertyMapTable.Record rec = new PropertyMapTable.Record(); 763 rec.Parent = token; 764 rec.PropertyList = this.ModuleBuilder.Property.RowCount + 1; 765 this.ModuleBuilder.PropertyMap.AddRecord(rec); 766 foreach (PropertyBuilder pb in properties) 767 { 768 pb.Bake(); 769 } 770 } 771 if (events != null) 772 { 773 EventMapTable.Record rec = new EventMapTable.Record(); 774 rec.Parent = token; 775 rec.EventList = this.ModuleBuilder.Event.RowCount + 1; 776 this.ModuleBuilder.EventMap.AddRecord(rec); 777 foreach (EventBuilder eb in events) 778 { 779 eb.Bake(); 780 } 781 } 782 } 783 784 public override Type BaseType 785 { 786 get 787 { 788 if (lazyBaseType == null && !IsInterface) 789 { 790 Type obj = Module.universe.System_Object; 791 if (this != obj) 792 { 793 lazyBaseType = obj; 794 } 795 } 796 return lazyBaseType; 797 } 798 } 799 800 public override string FullName 801 { 802 get 803 { 804 if (this.IsNested) 805 { 806 return this.DeclaringType.FullName + "+" + TypeNameParser.Escape(name); 807 } 808 if (ns == null) 809 { 810 return TypeNameParser.Escape(name); 811 } 812 else 813 { 814 return TypeNameParser.Escape(ns) + "." + TypeNameParser.Escape(name); 815 } 816 } 817 } 818 819 internal override TypeName TypeName 820 { 821 get { return new TypeName(ns, name); } 822 } 823 824 public override string Name 825 { 826 // FXBUG for a TypeBuilder the name is not escaped 827 get { return name; } 828 } 829 830 public override string Namespace 831 { 832 get 833 { 834 // for some reason, TypeBuilder doesn't return null (and mcs depends on this) 835 // note also that we don't return the declaring type namespace for nested types 836 return ns ?? ""; 837 } 838 } 839 840 public override TypeAttributes Attributes 841 { 842 get { return attribs; } 843 } 844 __SetAttributes(TypeAttributes attributes)845 public void __SetAttributes(TypeAttributes attributes) 846 { 847 this.attribs = attributes; 848 } 849 __GetDeclaredInterfaces()850 public override Type[] __GetDeclaredInterfaces() 851 { 852 return Util.ToArray(interfaces, Type.EmptyTypes); 853 } 854 __GetDeclaredMethods()855 public override MethodBase[] __GetDeclaredMethods() 856 { 857 MethodBase[] methods = new MethodBase[this.methods.Count]; 858 for (int i = 0; i < methods.Length; i++) 859 { 860 MethodBuilder mb = this.methods[i]; 861 if (mb.IsConstructor) 862 { 863 methods[i] = new ConstructorInfoImpl(mb); 864 } 865 else 866 { 867 methods[i] = mb; 868 } 869 } 870 return methods; 871 } 872 873 public override Type DeclaringType 874 { 875 get { return owner as TypeBuilder; } 876 } 877 878 public override bool IsGenericType 879 { 880 get { return IsGenericTypeDefinition; } 881 } 882 883 public override bool IsGenericTypeDefinition 884 { 885 get { return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0; } 886 } 887 888 public override int MetadataToken 889 { 890 get { return token; } 891 } 892 DefineUninitializedData(string name, int size, FieldAttributes attributes)893 public FieldBuilder DefineUninitializedData(string name, int size, FieldAttributes attributes) 894 { 895 return DefineInitializedData(name, new byte[size], attributes); 896 } 897 DefineInitializedData(string name, byte[] data, FieldAttributes attributes)898 public FieldBuilder DefineInitializedData(string name, byte[] data, FieldAttributes attributes) 899 { 900 Type fieldType = this.ModuleBuilder.GetType("$ArrayType$" + data.Length); 901 if (fieldType == null) 902 { 903 TypeBuilder tb = this.ModuleBuilder.DefineType("$ArrayType$" + data.Length, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.ExplicitLayout, this.Module.universe.System_ValueType, PackingSize.Size1, data.Length); 904 tb.CreateType(); 905 fieldType = tb; 906 } 907 FieldBuilder fb = DefineField(name, fieldType, attributes | FieldAttributes.Static); 908 fb.__SetDataAndRVA(data); 909 return fb; 910 } 911 GetMethod(Type type, MethodInfo method)912 public static MethodInfo GetMethod(Type type, MethodInfo method) 913 { 914 return new GenericMethodInstance(type, method, null); 915 } 916 GetConstructor(Type type, ConstructorInfo constructor)917 public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) 918 { 919 return new ConstructorInfoImpl(GetMethod(type, constructor.GetMethodInfo())); 920 } 921 GetField(Type type, FieldInfo field)922 public static FieldInfo GetField(Type type, FieldInfo field) 923 { 924 return new GenericFieldInstance(type, field); 925 } 926 927 public override Module Module 928 { 929 get { return owner.ModuleBuilder; } 930 } 931 932 public TypeToken TypeToken 933 { 934 get { return new TypeToken(token); } 935 } 936 WriteTypeDefRecord(MetadataWriter mw, ref int fieldList, ref int methodList)937 internal void WriteTypeDefRecord(MetadataWriter mw, ref int fieldList, ref int methodList) 938 { 939 mw.Write((int)attribs); 940 mw.WriteStringIndex(typeName); 941 mw.WriteStringIndex(typeNameSpace); 942 mw.WriteTypeDefOrRef(extends); 943 mw.WriteField(fieldList); 944 mw.WriteMethodDef(methodList); 945 methodList += methods.Count; 946 fieldList += fields.Count; 947 } 948 WriteMethodDefRecords(int baseRVA, MetadataWriter mw, ref int paramList)949 internal void WriteMethodDefRecords(int baseRVA, MetadataWriter mw, ref int paramList) 950 { 951 foreach (MethodBuilder mb in methods) 952 { 953 mb.WriteMethodDefRecord(baseRVA, mw, ref paramList); 954 } 955 } 956 ResolveMethodAndFieldTokens(ref int methodToken, ref int fieldToken, ref int parameterToken)957 internal void ResolveMethodAndFieldTokens(ref int methodToken, ref int fieldToken, ref int parameterToken) 958 { 959 foreach (MethodBuilder method in methods) 960 { 961 method.FixupToken(methodToken++, ref parameterToken); 962 } 963 foreach (FieldBuilder field in fields) 964 { 965 field.FixupToken(fieldToken++); 966 } 967 } 968 WriteParamRecords(MetadataWriter mw)969 internal void WriteParamRecords(MetadataWriter mw) 970 { 971 foreach (MethodBuilder mb in methods) 972 { 973 mb.WriteParamRecords(mw); 974 } 975 } 976 WriteFieldRecords(MetadataWriter mw)977 internal void WriteFieldRecords(MetadataWriter mw) 978 { 979 foreach (FieldBuilder fb in fields) 980 { 981 fb.WriteFieldRecords(mw); 982 } 983 } 984 985 internal ModuleBuilder ModuleBuilder 986 { 987 get { return owner.ModuleBuilder; } 988 } 989 990 ModuleBuilder ITypeOwner.ModuleBuilder 991 { 992 get { return owner.ModuleBuilder; } 993 } 994 GetModuleBuilderToken()995 internal override int GetModuleBuilderToken() 996 { 997 return token; 998 } 999 1000 internal bool HasNestedTypes 1001 { 1002 get { return (typeFlags & TypeFlags.HasNestedTypes) != 0; } 1003 } 1004 1005 // helper for ModuleBuilder.ResolveMethod() LookupMethod(int token)1006 internal MethodBase LookupMethod(int token) 1007 { 1008 foreach (MethodBuilder method in methods) 1009 { 1010 if (method.MetadataToken == token) 1011 { 1012 return method; 1013 } 1014 } 1015 return null; 1016 } 1017 IsCreated()1018 public bool IsCreated() 1019 { 1020 return (typeFlags & TypeFlags.Baked) != 0; 1021 } 1022 CheckBaked()1023 internal override void CheckBaked() 1024 { 1025 if ((typeFlags & TypeFlags.Baked) == 0) 1026 { 1027 throw new NotSupportedException(); 1028 } 1029 } 1030 __GetDeclaredTypes()1031 public override Type[] __GetDeclaredTypes() 1032 { 1033 if (this.HasNestedTypes) 1034 { 1035 List<Type> types = new List<Type>(); 1036 List<int> classes = this.ModuleBuilder.NestedClass.GetNestedClasses(token); 1037 foreach (int nestedClass in classes) 1038 { 1039 types.Add(this.ModuleBuilder.ResolveType(nestedClass)); 1040 } 1041 return types.ToArray(); 1042 } 1043 else 1044 { 1045 return Type.EmptyTypes; 1046 } 1047 } 1048 __GetDeclaredFields()1049 public override FieldInfo[] __GetDeclaredFields() 1050 { 1051 return Util.ToArray(fields, Empty<FieldInfo>.Array); 1052 } 1053 __GetDeclaredEvents()1054 public override EventInfo[] __GetDeclaredEvents() 1055 { 1056 return Util.ToArray(events, Empty<EventInfo>.Array); 1057 } 1058 __GetDeclaredProperties()1059 public override PropertyInfo[] __GetDeclaredProperties() 1060 { 1061 return Util.ToArray(properties, Empty<PropertyInfo>.Array); 1062 } 1063 1064 internal override bool IsModulePseudoType 1065 { 1066 get { return token == 0x02000001; } 1067 } 1068 1069 internal override bool IsBaked 1070 { 1071 get { return IsCreated(); } 1072 } 1073 } 1074 1075 sealed class BakedType : TypeInfo 1076 { BakedType(TypeBuilder typeBuilder)1077 internal BakedType(TypeBuilder typeBuilder) 1078 : base(typeBuilder) 1079 { 1080 } 1081 1082 public override string AssemblyQualifiedName 1083 { 1084 get { return underlyingType.AssemblyQualifiedName; } 1085 } 1086 1087 public override Type BaseType 1088 { 1089 get { return underlyingType.BaseType; } 1090 } 1091 1092 internal override TypeName TypeName 1093 { 1094 get { return underlyingType.TypeName; } 1095 } 1096 1097 public override string Name 1098 { 1099 // we need to escape here, because TypeBuilder.Name does not escape 1100 get { return TypeNameParser.Escape(underlyingType.__Name); } 1101 } 1102 1103 public override string FullName 1104 { 1105 get { return GetFullName(); } 1106 } 1107 1108 public override TypeAttributes Attributes 1109 { 1110 get { return underlyingType.Attributes; } 1111 } 1112 __GetDeclaredInterfaces()1113 public override Type[] __GetDeclaredInterfaces() 1114 { 1115 return underlyingType.__GetDeclaredInterfaces(); 1116 } 1117 __GetDeclaredMethods()1118 public override MethodBase[] __GetDeclaredMethods() 1119 { 1120 return underlyingType.__GetDeclaredMethods(); 1121 } 1122 __GetMethodImplMap()1123 public override __MethodImplMap __GetMethodImplMap() 1124 { 1125 return underlyingType.__GetMethodImplMap(); 1126 } 1127 __GetDeclaredFields()1128 public override FieldInfo[] __GetDeclaredFields() 1129 { 1130 return underlyingType.__GetDeclaredFields(); 1131 } 1132 __GetDeclaredEvents()1133 public override EventInfo[] __GetDeclaredEvents() 1134 { 1135 return underlyingType.__GetDeclaredEvents(); 1136 } 1137 __GetDeclaredProperties()1138 public override PropertyInfo[] __GetDeclaredProperties() 1139 { 1140 return underlyingType.__GetDeclaredProperties(); 1141 } 1142 __GetDeclaredTypes()1143 public override Type[] __GetDeclaredTypes() 1144 { 1145 return underlyingType.__GetDeclaredTypes(); 1146 } 1147 1148 public override Type DeclaringType 1149 { 1150 get { return underlyingType.DeclaringType; } 1151 } 1152 __GetLayout(out int packingSize, out int typeSize)1153 public override bool __GetLayout(out int packingSize, out int typeSize) 1154 { 1155 return underlyingType.__GetLayout(out packingSize, out typeSize); 1156 } 1157 GetGenericArguments()1158 public override Type[] GetGenericArguments() 1159 { 1160 return underlyingType.GetGenericArguments(); 1161 } 1162 GetGenericTypeArgument(int index)1163 internal override Type GetGenericTypeArgument(int index) 1164 { 1165 return underlyingType.GetGenericTypeArgument(index); 1166 } 1167 __GetGenericArgumentsCustomModifiers()1168 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers() 1169 { 1170 return underlyingType.__GetGenericArgumentsCustomModifiers(); 1171 } 1172 1173 public override bool IsGenericType 1174 { 1175 get { return underlyingType.IsGenericType; } 1176 } 1177 1178 public override bool IsGenericTypeDefinition 1179 { 1180 get { return underlyingType.IsGenericTypeDefinition; } 1181 } 1182 1183 public override bool ContainsGenericParameters 1184 { 1185 get { return underlyingType.ContainsGenericParameters; } 1186 } 1187 1188 public override int MetadataToken 1189 { 1190 get { return underlyingType.MetadataToken; } 1191 } 1192 1193 public override Module Module 1194 { 1195 get { return underlyingType.Module; } 1196 } 1197 GetModuleBuilderToken()1198 internal override int GetModuleBuilderToken() 1199 { 1200 return underlyingType.GetModuleBuilderToken(); 1201 } 1202 1203 internal override bool IsBaked 1204 { 1205 get { return true; } 1206 } 1207 } 1208 } 1209