private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) { record.Name = HandleString(entity.Name); record.Signature = new FieldSignature { Type = HandleType(entity.FieldType), // TODO: CustomModifiers }; record.Flags = GetFieldAttributes(entity); var ecmaField = entity as Cts.Ecma.EcmaField; if (ecmaField != null) { Ecma.MetadataReader reader = ecmaField.MetadataReader; Ecma.FieldDefinition fieldDef = reader.GetFieldDefinition(ecmaField.Handle); Ecma.ConstantHandle defaultValueHandle = fieldDef.GetDefaultValue(); if (!defaultValueHandle.IsNil) { record.DefaultValue = HandleConstant(ecmaField.Module, defaultValueHandle); } Ecma.CustomAttributeHandleCollection customAttributes = fieldDef.GetCustomAttributes(); if (customAttributes.Count > 0) { record.CustomAttributes = HandleCustomAttributes(ecmaField.Module, customAttributes); } } // TODO: Offset }
private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property); Ecma.PropertyAccessors acc = propDef.GetAccessors(); Cts.MethodDesc getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter); Cts.MethodDesc setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter); bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod); bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod); // Policy: If neither the getter nor setter have metadata, property doesn't have metadata if (!getterHasMetadata && !setterHasMetadata) { return(null); } Ecma.BlobReader sigBlobReader = reader.GetBlobReader(propDef.Signature); Cts.PropertySignature sig = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader, Cts.NotFoundBehavior.Throw).ParsePropertySignature(); Property result = new Property { Name = HandleString(reader.GetString(propDef.Name)), Flags = propDef.Attributes, Signature = new PropertySignature { CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis, Type = HandleType(sig.ReturnType) }, }; result.Signature.Parameters.Capacity = sig.Length; for (int i = 0; i < sig.Length; i++) { result.Signature.Parameters.Add(HandleType(sig[i])); } if (getterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Getter, Method = HandleMethodDefinition(getterMethod), }); } if (setterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Setter, Method = HandleMethodDefinition(setterMethod), }); } Ecma.ConstantHandle defaultValue = propDef.GetDefaultValue(); if (!defaultValue.IsNil) { result.DefaultValue = HandleConstant(module, defaultValue); } Ecma.CustomAttributeHandleCollection customAttributes = propDef.GetCustomAttributes(); if (customAttributes.Count > 0) { result.CustomAttributes = HandleCustomAttributes(module, customAttributes); } return(result); }
private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) { record.Name = HandleString(entity.Name); record.Signature = HandleMethodSignature(entity.Signature); if (entity.HasInstantiation) { record.GenericParameters.Capacity = entity.Instantiation.Length; foreach (var p in entity.Instantiation) { record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p)); } } var ecmaEntity = entity as Cts.Ecma.EcmaMethod; if (ecmaEntity != null) { Ecma.MetadataReader reader = ecmaEntity.MetadataReader; Ecma.MethodDefinition methodDef = reader.GetMethodDefinition(ecmaEntity.Handle); Ecma.ParameterHandleCollection paramHandles = methodDef.GetParameters(); record.Parameters.Capacity = paramHandles.Count; foreach (var paramHandle in paramHandles) { Ecma.Parameter param = reader.GetParameter(paramHandle); Parameter paramRecord = new Parameter { Flags = param.Attributes, Name = HandleString(reader.GetString(param.Name)), Sequence = checked ((ushort)param.SequenceNumber) }; Ecma.ConstantHandle defaultValue = param.GetDefaultValue(); if (!defaultValue.IsNil) { paramRecord.DefaultValue = HandleConstant(ecmaEntity.Module, defaultValue); } Ecma.CustomAttributeHandleCollection paramAttributes = param.GetCustomAttributes(); if (paramAttributes.Count > 0) { paramRecord.CustomAttributes = HandleCustomAttributes(ecmaEntity.Module, paramAttributes); } record.Parameters.Add(paramRecord); } Ecma.CustomAttributeHandleCollection attributes = methodDef.GetCustomAttributes(); if (attributes.Count > 0) { record.CustomAttributes = HandleCustomAttributes(ecmaEntity.Module, attributes); } } else { throw new NotImplementedException(); } record.Flags = GetMethodAttributes(entity); record.ImplFlags = GetMethodImplAttributes(entity); //TODO: RVA }
private MetadataRecord HandleConstant(Cts.Ecma.EcmaModule module, Ecma.ConstantHandle constantHandle) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.Constant constant = reader.GetConstant(constantHandle); Ecma.BlobReader blob = reader.GetBlobReader(constant.Value); switch (constant.TypeCode) { case ConstantTypeCode.Boolean: return(new ConstantBooleanValue { Value = blob.ReadBoolean() }); case ConstantTypeCode.Byte: return(new ConstantByteValue { Value = blob.ReadByte() }); case ConstantTypeCode.Char: return(new ConstantCharValue { Value = blob.ReadChar() }); case ConstantTypeCode.Double: return(new ConstantDoubleValue { Value = blob.ReadDouble() }); case ConstantTypeCode.Int16: return(new ConstantInt16Value { Value = blob.ReadInt16() }); case ConstantTypeCode.Int32: return(new ConstantInt32Value { Value = blob.ReadInt32() }); case ConstantTypeCode.Int64: return(new ConstantInt64Value { Value = blob.ReadInt64() }); case ConstantTypeCode.SByte: return(new ConstantSByteValue { Value = blob.ReadSByte() }); case ConstantTypeCode.Single: return(new ConstantSingleValue { Value = blob.ReadSingle() }); case ConstantTypeCode.String: return(HandleString(blob.ReadUTF16(blob.Length))); case ConstantTypeCode.UInt16: return(new ConstantUInt16Value { Value = blob.ReadUInt16() }); case ConstantTypeCode.UInt32: return(new ConstantUInt32Value { Value = blob.ReadUInt32() }); case ConstantTypeCode.UInt64: return(new ConstantUInt64Value { Value = blob.ReadUInt64() }); case ConstantTypeCode.NullReference: return(new ConstantReferenceValue()); default: throw new BadImageFormatException(); } }