Beispiel #1
0
        private void FinalizeParametersInMethod(MethodDefinition method, ref uint paramList, ref bool paramPtrRequired)
        {
            var pointerTable = Metadata.TablesStream.GetTable <ParameterPointerRow>(TableIndex.ParamPtr);

            for (int i = 0; i < method.ParameterDefinitions.Count; i++)
            {
                var parameter = method.ParameterDefinitions[i];

                var newToken = GetParameterDefinitionToken(parameter);
                if (newToken == MetadataToken.Zero)
                {
                    DiagnosticBag.RegisterException(new MetadataBuilderException(
                                                        $"An attempt was made to finalize parameter {parameter.SafeToString()} in {method.SafeToString()}, which was not added to the .NET directory buffer yet."));
                }

                // Add parameter pointer row, making sure the RID is preserved.
                // We only really need the parameter pointer table if the next RID is not the RID that we would expect
                // from a normal sequential layout of the table.
                if (newToken.Rid != pointerTable.Count + 1)
                {
                    paramPtrRequired = true;
                }
                pointerTable.Add(new ParameterPointerRow(newToken.Rid));

                // Add remaining metadata.
                AddCustomAttributes(newToken, parameter);
                AddConstant(newToken, parameter.Constant);
                AddFieldMarshal(newToken, parameter);
            }

            paramList += (uint)method.ParameterDefinitions.Count;
        }
Beispiel #2
0
        private void AddMethodPointers(TypeDefinition type, ref bool methodPtrRequired)
        {
            var pointerTable = Metadata.TablesStream.GetTable <MethodPointerRow>(TableIndex.MethodPtr);

            for (int i = 0; i < type.Methods.Count; i++)
            {
                var method = type.Methods[i];

                var newToken = GetMethodDefinitionToken(method);
                if (newToken == MetadataToken.Zero)
                {
                    DiagnosticBag.RegisterException(new MetadataBuilderException(
                                                        $"An attempt was made to finalize method {method.SafeToString()}, which was not added to the .NET directory buffer yet."));
                }

                // Add method pointer row, making sure the RID is preserved.
                // We only really need the method pointer table if the next RID is not the RID that we would expect
                // from a normal sequential layout of the table.
                if (newToken.Rid != pointerTable.Count + 1)
                {
                    methodPtrRequired = true;
                }
                pointerTable.Add(new MethodPointerRow(newToken.Rid));
            }
        }
Beispiel #3
0
        private void FinalizeFieldsInType(TypeDefinition type, ref bool fieldPtrRequired)
        {
            var pointerTable = Metadata.TablesStream.GetTable <FieldPointerRow>(TableIndex.FieldPtr);

            for (int i = 0; i < type.Fields.Count; i++)
            {
                var field = type.Fields[i];

                var newToken = GetFieldDefinitionToken(field);
                if (newToken == MetadataToken.Zero)
                {
                    DiagnosticBag.RegisterException(new MetadataBuilderException(
                                                        $"An attempt was made to finalize field {field.SafeToString()}, which was not added to the .NET directory buffer yet."));
                }

                // Add field pointer row, making sure the RID is preserved.
                // We only really need the field pointer table if the next RID is not the RID that we would expect
                // from a normal sequential layout of the table.
                if (newToken.Rid != pointerTable.Count + 1)
                {
                    fieldPtrRequired = true;
                }
                pointerTable.Add(new FieldPointerRow(newToken.Rid));

                AddCustomAttributes(newToken, field);
                AddConstant(newToken, field.Constant);
                AddImplementationMap(newToken, field.ImplementationMap);
                AddFieldRva(newToken, field);
                AddFieldLayout(newToken, field);
                AddFieldMarshal(newToken, field);
            }
        }
        private bool AssertIsImported(IModuleProvider member)
        {
            if (member.Module != Module)
            {
                DiagnosticBag.RegisterException(new MemberNotImportedException((IMetadataMember)member));
                return(false);
            }

            return(true);
        }
        private void FinalizeMethodsInType(
            TypeDefinition type,
            ref bool methodPtrRequired,
            ref uint paramList,
            ref bool paramPtrRequired)
        {
            var definitionTable = Metadata.TablesStream.GetTable <MethodDefinitionRow>(TableIndex.Method);
            var pointerTable    = Metadata.TablesStream.GetTable <MethodPointerRow>(TableIndex.MethodPtr);

            var context = new MethodBodySerializationContext(this, SymbolsProvider, DiagnosticBag);

            for (int i = 0; i < type.Methods.Count; i++)
            {
                var method = type.Methods[i];

                var newToken = GetMethodDefinitionToken(method);
                if (newToken == MetadataToken.Zero)
                {
                    DiagnosticBag.RegisterException(new MetadataBuilderException(
                                                        $"An attempt was made to finalize method {method.SafeToString()}, which was not added to the .NET directory buffer yet."));
                }

                // Add method pointer row, making sure the RID is preserved.
                // We only really need the method pointer table if the next RID is not the RID that we would expect
                // from a normal sequential layout of the table.
                if (newToken.Rid != pointerTable.Count + 1)
                {
                    methodPtrRequired = true;
                }
                pointerTable.Add(new MethodPointerRow(newToken.Rid));

                // Serialize method body and update column.
                var row = definitionTable[newToken.Rid];

                definitionTable[newToken.Rid] = new MethodDefinitionRow(
                    MethodBodySerializer.SerializeMethodBody(context, method),
                    row.ImplAttributes,
                    row.Attributes,
                    row.Name,
                    row.Signature,
                    paramList);

                // Finalize parameters.
                FinalizeParametersInMethod(method, ref paramList, ref paramPtrRequired);

                // Add remaining metadata.
                AddCustomAttributes(newToken, method);
                AddSecurityDeclarations(newToken, method);
                AddImplementationMap(newToken, method.ImplementationMap);
                DefineGenericParameters(newToken, method);
            }
        }
Beispiel #6
0
        private void FinalizePropertiesInType(TypeDefinition type, uint typeRid, ref uint propertyList,
                                              ref bool propertyPtrRequired)
        {
            // Don't emit property map rows when the type does not define any properties.
            if (type.Properties.Count == 0)
            {
                return;
            }

            var mapTable     = Metadata.TablesStream.GetSortedTable <TypeDefinition, PropertyMapRow>(TableIndex.PropertyMap);
            var pointerTable = Metadata.TablesStream.GetTable <PropertyPointerRow>(TableIndex.PropertyPtr);

            for (int i = 0; i < type.Properties.Count; i++)
            {
                var property = type.Properties[i];

                var newToken = GetPropertyDefinitionToken(property);
                if (newToken == MetadataToken.Zero)
                {
                    DiagnosticBag.RegisterException(new MetadataBuilderException(
                                                        $"An attempt was made to finalize property {property.SafeToString()}, which was not added to the .NET directory buffer yet."));
                }

                // Add property pointer row, making sure the RID is preserved.
                // We only really need the property pointer table if the next RID is not the RID that we would expect
                // from a normal sequential layout of the table.
                if (newToken.Rid != pointerTable.Count + 1)
                {
                    propertyPtrRequired = true;
                }
                pointerTable.Add(new PropertyPointerRow(newToken.Rid));

                // Add remaining metadata.
                AddCustomAttributes(newToken, property);
                AddMethodSemantics(newToken, property);
                AddConstant(newToken, property.Constant);
            }

            // Map the type to the property list.
            var row = new PropertyMapRow(typeRid, propertyList);

            mapTable.Add(type, row);
            propertyList += (uint)type.Properties.Count;
        }
Beispiel #7
0
        /// <summary>
        /// Allocates metadata rows for the provided type definitions in the buffer.
        /// </summary>
        /// <param name="types">The types to define.</param>
        /// <remarks>
        /// This method does not define any member defined in the type, except for nested types.
        /// </remarks>
        public void DefineTypes(IEnumerable <TypeDefinition> types)
        {
            var typeDefTable     = Metadata.TablesStream.GetTable <TypeDefinitionRow>(TableIndex.TypeDef);
            var nestedClassTable = Metadata.TablesStream.GetSortedTable <TypeDefinition, NestedClassRow>(TableIndex.NestedClass);

            foreach (var type in types)
            {
                // At this point, we might not have added all type defs/refs/specs yet, so we cannot determine
                // the extends column, nor determine the field and method lists of this type.

                var row = new TypeDefinitionRow(
                    type.Attributes,
                    Metadata.StringsStream.GetStringIndex(type.Name),
                    Metadata.StringsStream.GetStringIndex(type.Namespace),
                    0,
                    0,
                    0);

                var token = typeDefTable.Add(row);
                _tokenMapping.Register(type, token);

                if (type.IsNested)
                {
                    // As per the ECMA-335; nested types should always follow their enclosing types in the TypeDef table.
                    // Proper type def collections that are passed onto this function therefore should have been added
                    // already to the buffer. If not, we have an invalid ordering of types.

                    var enclosingTypeToken = GetTypeDefinitionToken(type.DeclaringType);
                    if (enclosingTypeToken.Rid == 0)
                    {
                        DiagnosticBag.RegisterException(new MetadataBuilderException(
                                                            $"Nested type {type.SafeToString()} is added before its enclosing class {type.DeclaringType.SafeToString()}."));
                    }

                    var nestedClassRow = new NestedClassRow(
                        token.Rid,
                        enclosingTypeToken.Rid);

                    nestedClassTable.Add(type, nestedClassRow);
                }
            }
        }