public void TypeOrMethodDef() { Assert.Equal(0, CodedIndex.TypeOrMethodDef(default(TypeDefinitionHandle))); Assert.Equal((0xffffff << 1) | 1, CodedIndex.TypeOrMethodDef(MetadataTokens.MethodDefinitionHandle(0xffffff))); Assert.Equal(0x02 | 0, CodedIndex.TypeOrMethodDef(MetadataTokens.TypeDefinitionHandle(1))); Assert.Equal(0x02 | 1, CodedIndex.TypeOrMethodDef(MetadataTokens.MethodDefinitionHandle(1))); }
public void Errors() { var badHandleKind = CustomAttributeHandle.FromRowId(1); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasCustomAttribute(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasConstant(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.CustomAttributeType(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasDeclSecurity(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasFieldMarshal(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasSemantics(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.Implementation(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MemberForwarded(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MemberRefParent(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.MethodDefOrRef(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.ResolutionScope(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeDefOrRef(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeDefOrRefOrSpec(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.TypeOrMethodDef(badHandleKind)); AssertExtensions.Throws <ArgumentException>(null, () => CodedIndex.HasCustomDebugInformation(badHandleKind)); }
private void _sortAndWriteGenParamEntries(ref DynamicArray <GenericParameter> entriesList) { if (entriesList.length == 0) { return; } var entries = entriesList.asReadOnlyArrayView(); var codedIndexKeys = new int[entries.length]; for (int i = 0; i < entries.length; i++) { codedIndexKeys[i] = CodedIndex.TypeOrMethodDef(entries[i].ownerHandle); } Array.Sort(codedIndexKeys, entriesList.getUnderlyingArray(), 0, entriesList.length); using var mdBuilder = m_metadataContext.getMetadataBuilder(); for (int i = 0; i < entries.length; i++) { ref readonly var genParam = ref entries[i];
private void CreateMethod(MethodInfo method, List <DelayedWrite> genericParams) { if (!_metadata.TryGetMethodDefinition(method, out var metadata)) { ThrowMetadataIsNotReserved("Method", method); } EnsureMetadataWasNotEmitted(metadata, method); var body = method.GetMethodBody(); var localVariablesSignature = default(StandaloneSignatureHandle); if (body != null && body.LocalVariables.Count > 0) { localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob( MetadataHelper.BuildSignature(x => { x.LocalVariableSignature(body.LocalVariables.Count).AddRange(body.LocalVariables, _metadata); }))); } var offset = -1; // If body exists, we write it in IL body stream if (body != null && !method.IsAbstract) { var methodBodyWriter = new MethodBodyStreamWriter(_metadata); // offset can be aligned during serialization. So, override the correct offset. offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature); } var parameters = CreateParameters(method.GetParameters()); var handle = _metadata.Builder.AddMethodDefinition( method.Attributes, method.MethodImplementationFlags, _metadata.GetOrAddString(method.Name), _metadata.GetMethodOrConstructorSignature(method), offset, parameters); // The generation of interface method overrides has been moved to // AssemblyGenerator.DeclareInterfacesAndCreateInterfaceMap in // AssemblyGenerator.Types.cs. // Add generic parameters if (method.IsGenericMethodDefinition) { int index = 0; foreach (var arg in method.GetGenericArguments()) { genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () => { // Add the argument var gaHandle = _metadata.Builder.AddGenericParameter(handle, arg.GenericParameterAttributes, _metadata.GetOrAddString(arg.Name), index++); // Add it's constraints foreach (var constraint in arg.GetGenericParameterConstraints()) { _metadata.Builder.AddGenericParameterConstraint(gaHandle, _metadata.GetTypeHandle(constraint)); } })); } } else if (method.Attributes.HasFlag(MethodAttributes.PinvokeImpl)) { ProcessPInvokeMapData( method, out string libraryName, out string entryName, out MethodImportAttributes attrs); var libraryNameHandle = _metadata.GetOrAddString(libraryName); var moduleRefHandle = _metadata.Builder.AddModuleReference(libraryNameHandle); var entryNameHandle = _metadata.GetOrAddString(entryName); // Add the ImplMap entry for the P/Invoke _metadata.Builder.AddMethodImport( handle, attrs, entryNameHandle, moduleRefHandle); } VerifyEmittedHandle(metadata, handle); metadata.MarkAsEmitted(); CreateCustomAttributes(handle, method.GetCustomAttributesData()); }
private void CreateMethod(MethodInfo method, List <DelayedWrite> genericParams) { if (!_metadata.TryGetMethodDefinition(method, out var metadata)) { ThrowMetadataIsNotReserved("Method", method); } EnsureMetadataWasNotEmitted(metadata, method); var body = method.GetMethodBody(); var localVariablesSignature = default(StandaloneSignatureHandle); if (body != null && body.LocalVariables.Count > 0) { localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob( MetadataHelper.BuildSignature(x => { x.LocalVariableSignature(body.LocalVariables.Count).AddRange(body.LocalVariables, _metadata); }))); } var offset = -1; // If body exists, we write it in IL body stream if (body != null && !method.IsAbstract) { var methodBodyWriter = new MethodBodyStreamWriter(_metadata); // offset can be aligned during serialization. So, override the correct offset. offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature); } var parameters = CreateParameters(method.GetParameters()); var handle = _metadata.Builder.AddMethodDefinition( method.Attributes, method.MethodImplementationFlags, _metadata.GetOrAddString(method.Name), _metadata.GetMethodOrConstructorSignature(method), offset, parameters); // Explicit interface implementations need to be marked with method implementation // (This is the equivalent of .Override in msil) if (method.IsPrivate) { // Go through all the implemented interfaces and all their methods // looking for methods that this method implements and mark accordingly. // NB: This is not super efficient. Should probably create a map somewhere // for faster lookup, but this will do for now. var type = method.DeclaringType; foreach (var itf in type.GetInterfaces()) { var itfMap = type.GetInterfaceMap(itf); for (int i = 0; i < itfMap.TargetMethods.Length; i++) { var m = itfMap.TargetMethods[i]; if (m == method) { var itfImpl = itfMap.InterfaceMethods[i]; _metadata.Builder.AddMethodImplementation((TypeDefinitionHandle)_metadata.GetTypeHandle(method.DeclaringType), handle, _metadata.GetMethodHandle(itfImpl)); } } } } // Add generic parameters if (method.IsGenericMethodDefinition) { int index = 0; foreach (var arg in method.GetGenericArguments()) { genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () => { // Add the argument var gaHandle = _metadata.Builder.AddGenericParameter(handle, arg.GenericParameterAttributes, _metadata.GetOrAddString(arg.Name), index++); // Add it's constraints foreach (var constraint in arg.GetGenericParameterConstraints()) { _metadata.Builder.AddGenericParameterConstraint(gaHandle, _metadata.GetTypeHandle(constraint)); } })); } } VerifyEmittedHandle(metadata, handle); metadata.MarkAsEmitted(); CreateCustomAttributes(handle, method.GetCustomAttributesData()); }
private void CreateType(Type type, List <DelayedWrite> genericParams) { // Check reserved and not already emitted if (!_metadata.TryGetTypeDefinition(type, out var metadata)) { ThrowMetadataIsNotReserved("Type", type); } EnsureMetadataWasNotEmitted(metadata, type); // Add the type definition var baseTypeHandle = type.BaseType != null?_metadata.GetTypeHandle(type.BaseType) : default; var handle = _metadata.Builder.AddTypeDefinition( type.Attributes, type.DeclaringType == null ? _metadata.GetOrAddString(ApplyNameChange(type.Namespace)) : default(StringHandle), _metadata.GetOrAddString(type.Name), baseTypeHandle, MetadataTokens.FieldDefinitionHandle(_metadata.Builder.GetRowCount(TableIndex.Field) + 1), MetadataTokens.MethodDefinitionHandle(_metadata.Builder.GetRowCount(TableIndex.MethodDef) + 1)); // Verify and mark emitted VerifyEmittedHandle(metadata, handle); metadata.MarkAsEmitted(); // Setup pack and size attributes (if explicit layout) if (type.IsExplicitLayout) { _metadata.Builder.AddTypeLayout( handle, (ushort)type.StructLayoutAttribute.Pack, (uint)type.StructLayoutAttribute.Size ); } // Add implemented interfaces (not for enums though - eg: IComparable etc...) if (!type.IsEnum) { DeclareInterfacesAndCreateInterfaceMap(type, handle); } // Setup enclosing type if (type.DeclaringType != null) { _metadata.Builder.AddNestedType(handle, (TypeDefinitionHandle)_metadata.GetTypeHandle(type.DeclaringType)); } // Create attributes CreateCustomAttributes(handle, type.GetCustomAttributesData()); // Handle generics type if (type.IsGenericType) { if (type.IsGenericTypeDefinition) { var genericType = type.GetGenericTypeDefinition(); var typeInfo = genericType.GetTypeInfo(); int index = 0; foreach (var arg in typeInfo.GenericTypeParameters) { var attr = arg.GenericParameterAttributes; genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () => { var gpHandle = _metadata.Builder.AddGenericParameter(handle, attr, _metadata.GetOrAddString(arg.Name), index++); foreach (var constraint in arg.GetGenericParameterConstraints()) { _metadata.Builder.AddGenericParameterConstraint(gpHandle, _metadata.GetTypeHandle(constraint)); } })); } } } // Create members... CreateFields(type.GetFields(AllFields)); CreatePropertiesForType(type.GetProperties(AllProperties)); CreateEventsForType(type.GetEvents(AllEvents)); CreateConstructors(type.GetConstructors(AllMethods)); CreateMethods(type.GetMethods(AllMethods), genericParams); }
public ReservedBlob <GuidHandle> Import() { if (_reader.IsAssembly) { var srcAssembly = _reader.GetAssemblyDefinition(); _builder.AddAssembly(ImportValue(srcAssembly.Name), srcAssembly.Version, ImportValue(srcAssembly.Culture), ImportValue(srcAssembly.PublicKey), srcAssembly.Flags, srcAssembly.HashAlgorithm); Debug?.Invoke($"Imported assembly {_reader.ToString(srcAssembly)}"); } var srcModule = _reader.GetModuleDefinition(); var mvidBlob = _builder.ReserveGuid(); _builder.AddModule(srcModule.Generation, ImportValue(srcModule.Name), mvidBlob.Handle, ImportValue(srcModule.GenerationId), ImportValue(srcModule.BaseGenerationId)); Debug?.Invoke($"Imported module {_reader.ToString(srcModule)}"); Debug?.Invoke($"Importing assembly files"); foreach (var srcHandle in _reader.AssemblyFiles) { Import(srcHandle); } var index = 1; Debug?.Invoke($"Preparing type list for import"); var checker = new CachedAttributeChecker(); foreach (var srcHandle in _reader.TypeDefinitions) { bool shouldImport; var src = _reader.GetTypeDefinition(srcHandle); if (checker.HasAttribute(_reader, src, AttributeNames.Embedded) && checker.HasAttribute(_reader, src, AttributeNames.CompilerGenerated)) { Trace?.Invoke($"Embedded type found {_reader.ToString(srcHandle)}"); shouldImport = true; } else { shouldImport = Filter?.AllowImport(_reader.GetTypeDefinition(srcHandle), _reader) != false; } if (shouldImport) { _typeDefinitionCache[srcHandle] = MetadataTokens.TypeDefinitionHandle(index++); } else { Trace?.Invoke($"Type filtered and will not be imported {_reader.ToString(srcHandle)}"); } } Debug?.Invoke($"Importing type definitions"); foreach (var srcHandle in _reader.TypeDefinitions.Where(_typeDefinitionCache.ContainsKey)) { var dstHandle = ImportTypeDefinitionSkeleton(srcHandle); if (dstHandle != _typeDefinitionCache[srcHandle]) { throw new Exception("WTF: type handle mismatch"); } } Debug?.Invoke($"Importing type definition accessories"); foreach (var(srcHandle, dstHandle) in _typeDefinitionCache) { ImportTypeDefinitionAccessories(srcHandle, dstHandle); } Debug?.Invoke($"Importing method definition accessories"); foreach (var(srcHandle, dstHandle) in _methodDefinitionCache) { ImportMethodDefinitionAccessories(srcHandle, dstHandle); } Debug?.Invoke($"Importing field definition accessories"); foreach (var(srcHandle, dstHandle) in _fieldDefinitionCache) { ImportFieldDefinitionAccessories(srcHandle, dstHandle); } Debug?.Invoke($"Importing nested classes"); var nestedTypes = _typeDefinitionCache .Select(kv => Tuple.Create(kv.Value, _reader.GetTypeDefinition(kv.Key).GetNestedTypes())) .SelectMany(x => x.Item2.Select(y => Tuple.Create(x.Item1, y, Import(y)))) .Where(x => !x.Item3.IsNil) .OrderBy(x => RowId(x.Item3)) .ToList(); foreach (var(dstHandle, srcNested, dstNested) in nestedTypes) { _builder.AddNestedType(dstNested, dstHandle); Trace?.Invoke($"Imported nested type {_reader.ToString(srcNested)} -> {RowId(dstNested):X}"); } var generic = _typeDefinitionCache .Select(kv => Tuple.Create((EntityHandle)kv.Value, _reader.GetTypeDefinition(kv.Key).GetGenericParameters())) .Concat(_methodDefinitionCache .Select(kv => Tuple.Create((EntityHandle)kv.Value, _reader.GetMethodDefinition(kv.Key).GetGenericParameters()))) .OrderBy(x => CodedIndex.TypeOrMethodDef(x.Item1)) .ToList(); Debug?.Invoke($"Importing generic constraints"); foreach (var(dstHandle, genericParams) in generic) { ImportGenericConstraints(dstHandle, genericParams); } Debug?.Invoke($"Importing custom attributes"); foreach (var src in _reader.CustomAttributes) { Import(src); } Debug?.Invoke($"Importing declarative security attributes"); foreach (var src in _reader.DeclarativeSecurityAttributes) { Import(src); } Debug?.Invoke($"Importing exported types"); foreach (var src in _reader.ExportedTypes) { Import(src); } Debug?.Invoke($"Importing done"); return(mvidBlob); }