private BlobHandle GetFieldSignatureBlobHandle(FieldDesc field) { var fieldDef = field.GetTypicalFieldDefinition(); var embeddedSigData = field.GetEmbeddedSignatureData(); EmbeddedSignatureDataEmitter signatureDataEmitter; if (embeddedSigData != null && embeddedSigData.Length != 0) { signatureDataEmitter = new EmbeddedSignatureDataEmitter(embeddedSigData, this); } else { signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; } BlobBuilder memberRefSig = new BlobBuilder(); EncodeFieldSignature(memberRefSig, field.FieldType, signatureDataEmitter); if (!signatureDataEmitter.Complete) { throw new ArgumentException(); } var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); return(sigBlob); }
private BlobHandle GetMethodSignatureBlobHandle(MethodSignature sig) { EmbeddedSignatureDataEmitter signatureDataEmitter; if (sig.HasEmbeddedSignatureData) { signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); } else { signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; } BlobBuilder memberRefSig = new BlobBuilder(); EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); if (!signatureDataEmitter.Complete) { throw new ArgumentException(); } var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); return(sigBlob); }
void EncodeFieldSignature(BlobBuilder signatureBuilder, TypeDesc fieldType, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); signatureEncoder.FieldSignature(); EncodeType(signatureBuilder, fieldType, signatureDataEmitter); signatureDataEmitter.Pop(); }
public EntityHandle GetMethodRef(MethodDesc method) { if (_methodRefs.TryGetValue(method, out var handle)) { return(handle); } EntityHandle methodHandle; if (method.HasInstantiation && (method.GetMethodDefinition() != method)) { EntityHandle uninstantiatedHandle = GetMethodRef(method.GetMethodDefinition()); BlobBuilder methodSpecSig = new BlobBuilder(); BlobEncoder methodSpecEncoder = new BlobEncoder(methodSpecSig); methodSpecEncoder.MethodSpecificationSignature(method.Instantiation.Length); foreach (var type in method.Instantiation) { EncodeType(methodSpecSig, type, EmbeddedSignatureDataEmitter.EmptySingleton); } var methodSpecSigHandle = _metadataBuilder.GetOrAddBlob(methodSpecSig); methodHandle = _metadataBuilder.AddMethodSpecification(uninstantiatedHandle, methodSpecSigHandle); } else { EntityHandle typeHandle = GetTypeRef((MetadataType)method.OwningType); StringHandle methodName = _metadataBuilder.GetOrAddString(method.Name); var sig = method.GetTypicalMethodDefinition().Signature; EmbeddedSignatureDataEmitter signatureDataEmitter; if (sig.HasEmbeddedSignatureData) { signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); } else { signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; } BlobBuilder memberRefSig = new BlobBuilder(); EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); if (!signatureDataEmitter.Complete) { throw new ArgumentException(); } var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); methodHandle = _metadataBuilder.AddMemberReference(typeHandle, methodName, sigBlob); } _methodRefs.Add(method, methodHandle); return(methodHandle); }
void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); int genericParameterCount = sig.GenericParameterCount; bool isInstanceMethod = !sig.IsStatic; SignatureCallingConvention sigCallingConvention = SignatureCallingConvention.Default; switch (sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.CallingConventionVarargs: sigCallingConvention = SignatureCallingConvention.VarArgs; break; case MethodSignatureFlags.UnmanagedCallingConventionCdecl: sigCallingConvention = SignatureCallingConvention.CDecl; break; case MethodSignatureFlags.UnmanagedCallingConventionStdCall: sigCallingConvention = SignatureCallingConvention.StdCall; break; case MethodSignatureFlags.UnmanagedCallingConventionThisCall: sigCallingConvention = SignatureCallingConvention.ThisCall; break; case MethodSignatureFlags.UnmanagedCallingConvention: // [TODO] sigCallingConvention = SignatureCallingConvention.Unmanaged; sigCallingConvention = (SignatureCallingConvention)9; break; } signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); signatureBuilder.WriteCompressedInteger(sig.Length); // TODO Process custom modifiers in some way EncodeType(signatureBuilder, sig.ReturnType, signatureDataEmitter); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i], signatureDataEmitter); } signatureDataEmitter.Pop(); }
private void EncodeType(BlobBuilder blobBuilder, TypeDesc type, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); signatureDataEmitter.Push(); signatureDataEmitter.EmitAtCurrentIndexStack(blobBuilder); signatureDataEmitter.Pop(); signatureDataEmitter.Push(); if (type.IsPrimitive) { SignatureTypeCode primitiveCode; switch (type.Category) { case TypeFlags.Void: primitiveCode = SignatureTypeCode.Void; break; case TypeFlags.Boolean: primitiveCode = SignatureTypeCode.Boolean; break; case TypeFlags.Char: primitiveCode = SignatureTypeCode.Char; break; case TypeFlags.SByte: primitiveCode = SignatureTypeCode.SByte; break; case TypeFlags.Byte: primitiveCode = SignatureTypeCode.Byte; break; case TypeFlags.Int16: primitiveCode = SignatureTypeCode.Int16; break; case TypeFlags.UInt16: primitiveCode = SignatureTypeCode.UInt16; break; case TypeFlags.Int32: primitiveCode = SignatureTypeCode.Int32; break; case TypeFlags.UInt32: primitiveCode = SignatureTypeCode.UInt32; break; case TypeFlags.Int64: primitiveCode = SignatureTypeCode.Int64; break; case TypeFlags.UInt64: primitiveCode = SignatureTypeCode.UInt64; break; case TypeFlags.IntPtr: primitiveCode = SignatureTypeCode.IntPtr; break; case TypeFlags.UIntPtr: primitiveCode = SignatureTypeCode.UIntPtr; break; case TypeFlags.Single: primitiveCode = SignatureTypeCode.Single; break; case TypeFlags.Double: primitiveCode = SignatureTypeCode.Double; break; default: throw new Exception("Unknown primitive type"); } blobBuilder.WriteByte((byte)primitiveCode); } else if (type.IsSzArray) { blobBuilder.WriteByte((byte)SignatureTypeCode.SZArray); EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter); } else if (type.IsArray) { var arrayType = (ArrayType)type; blobBuilder.WriteByte((byte)SignatureTypeCode.Array); EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter); var shapeEncoder = new ArrayShapeEncoder(blobBuilder); // TODO Add support for non-standard array shapes shapeEncoder.Shape(arrayType.Rank, default(ImmutableArray <int>), default(ImmutableArray <int>)); } else if (type.IsPointer) { blobBuilder.WriteByte((byte)SignatureTypeCode.Pointer); EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter); } else if (type.IsFunctionPointer) { FunctionPointerType fnptrType = (FunctionPointerType)type; EncodeMethodSignature(blobBuilder, fnptrType.Signature, signatureDataEmitter); } else if (type.IsByRef) { blobBuilder.WriteByte((byte)SignatureTypeCode.ByReference); EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter); } else if (type.IsObject) { blobBuilder.WriteByte((byte)SignatureTypeCode.Object); } else if (type.IsString) { blobBuilder.WriteByte((byte)SignatureTypeCode.String); } else if (type.IsWellKnownType(WellKnownType.TypedReference)) { blobBuilder.WriteByte((byte)SignatureTypeCode.TypedReference); } else if (type.IsWellKnownType(WellKnownType.Void)) { blobBuilder.WriteByte((byte)SignatureTypeCode.Void); } else if (type is SignatureVariable) { SignatureVariable sigVar = (SignatureVariable)type; SignatureTypeCode code = sigVar.IsMethodSignatureVariable ? SignatureTypeCode.GenericMethodParameter : SignatureTypeCode.GenericTypeParameter; blobBuilder.WriteByte((byte)code); blobBuilder.WriteCompressedInteger(sigVar.Index); } else if (type is InstantiatedType) { blobBuilder.WriteByte((byte)SignatureTypeCode.GenericTypeInstance); EncodeType(blobBuilder, type.GetTypeDefinition(), signatureDataEmitter); blobBuilder.WriteCompressedInteger(type.Instantiation.Length); foreach (var instantiationArg in type.Instantiation) { EncodeType(blobBuilder, instantiationArg, signatureDataEmitter); } } else if (type is MetadataType) { var metadataType = (MetadataType)type; // Must be class or valuetype blobBuilder.WriteByte(type.IsValueType ? (byte)SignatureTypeKind.ValueType : (byte)SignatureTypeKind.Class); int codedIndex = CodedIndex.TypeDefOrRef(GetTypeRef(metadataType)); blobBuilder.WriteCompressedInteger(codedIndex); } else { throw new Exception("Unexpected type"); } signatureDataEmitter.Pop(); signatureDataEmitter.Pop(); }