private BlobHandle MakeSignatureHandle(MethodSignature signature) { BlobHandle handle; if (!_methodSignatureHandles.TryGetValue(signature, out handle)) { BlobBuilder metadataSignature = new BlobBuilder(); MethodSignatureEncoder methodSigEncoder = new BlobEncoder(metadataSignature).MethodSignature( SignatureCallingConvention.Default, signature.GenericParameterCount, !signature.IsStatic); ReturnTypeEncoder returnTypeEncoder; ParametersEncoder parametersEncoder; methodSigEncoder.Parameters(signature.Length, out returnTypeEncoder, out parametersEncoder); // Return Type Sig EncodeTypeSignature(returnTypeEncoder.Type(), signature.ReturnType); // Parameter Types Sig for (int i = 0; i < signature.Length; i++) { EncodeTypeSignature(parametersEncoder.AddParameter().Type(), signature[i]); } _methodSignatureHandles[signature] = handle = _metadataBuilder.GetOrAddBlob(metadataSignature); } return(handle); }
public void BlobEncoder_MethodSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); Assert.Same(b, e.Builder); var s = e.MethodSignature(); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); Assert.False(s.HasVarArgs); b.Clear(); s = e.MethodSignature( convention: SignatureCallingConvention.StdCall, genericParameterCount: 1234, isInstanceMethod: true); AssertEx.Equal(new byte[] { 0x32, 0x84, 0xD2 }, b.ToArray()); Assert.False(s.HasVarArgs); b.Clear(); s = e.MethodSignature( convention: SignatureCallingConvention.VarArgs, genericParameterCount: 1, isInstanceMethod: false); AssertEx.Equal(new byte[] { 0x15, 0x01 }, b.ToArray()); Assert.True(s.HasVarArgs); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: -1)); Assert.Throws <ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: ushort.MaxValue + 1)); }
public void CreateCustomAttributes(EntityHandle parent, IEnumerable <CustomAttributeData> attributes) { foreach (var attr in attributes) { // Get the attribute type and make sure handle created var attrType = attr.AttributeType; // Check if the supplied attribute should be emitted or is encoded // directly in metadata. if (s_PseudoAttributes.Contains(attrType)) { continue; } var attrTypeHandle = _metadata.GetTypeHandle(attrType); // create type // Get handle to the constructor var ctorHandle = _metadata.GetConstructorHandle(attr.Constructor); System.Diagnostics.Debug.Assert(!ctorHandle.IsNil); // Encode the attribute values var enc = new BlobEncoder(new BlobBuilder()); enc.CustomAttributeSignature( (fa) => EncodeFixedAttributes(fa, attr), (na) => EncodeNamedAttributes(na, attr) ); // Add attribute to the entity _metadata.Builder.AddCustomAttribute(parent, ctorHandle, _metadata.Builder.GetOrAddBlob(enc.Builder)); } }
public static void Assembly_reference_with_flag(AssemblyFlags flag) { var builder = BuildAssembly(); var baseType = typeof(AttributeTargets); var baseTypeAssemblyName = baseType.Assembly.GetName(); var assemblyReferenceHandle = builder.AddAssemblyReference( builder.GetOrAddString(baseTypeAssemblyName.Name), baseTypeAssemblyName.Version, builder.GetOrAddString(baseTypeAssemblyName.CultureName), builder.GetOrAddBlob((baseTypeAssemblyName.Flags & AssemblyNameFlags.PublicKey) != 0 ? baseTypeAssemblyName.GetPublicKey() : baseTypeAssemblyName.GetPublicKeyToken()), (AssemblyFlags)baseTypeAssemblyName.Flags | flag, hashValue: default); var typeReferenceHandle = builder.AddTypeReference( assemblyReferenceHandle, builder.GetOrAddString(baseType.Namespace), builder.GetOrAddString(baseType.Name)); var fieldTypeBlob = new BlobBuilder(); var fieldTypeEncoder = new BlobEncoder(fieldTypeBlob).FieldSignature(); fieldTypeEncoder.Type(typeReferenceHandle, isValueType: false); var fieldHandle = builder.AddFieldDefinition( FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal, builder.GetOrAddString("TestField"), builder.GetOrAddBlob(fieldTypeBlob)); builder.AddConstant(fieldHandle, null); builder.AddTypeDefinition( TypeAttributes.Public, @namespace: default,
public int AddMethodBody(MethodBase methodBase, StandaloneSignatureHandle localVariablesSignature = default) { var body = methodBase.GetMethodBody(); if (body == null) { return(_metadata.ILBuilder.Count); } var localVariables = body.LocalVariables.ToArray(); var localEncoder = new BlobEncoder(new BlobBuilder()).LocalVariableSignature(localVariables.Length); localEncoder.AddRange(localVariables, _metadata); var instructions = methodBase.GetInstructions(); var maxStack = body.MaxStackSize; var codeSize = body.GetILAsByteArray().Length; var exceptionRegionCount = body.ExceptionHandlingClauses.Count; var attributes = body.InitLocals ? MethodBodyAttributes.InitLocals : MethodBodyAttributes.None; var hasDynamicStackAllocation = instructions.Any(x => x.OpCode == OpCodes.Localloc); // Header var offset = SerializeHeader(codeSize, maxStack, exceptionRegionCount, attributes, localVariablesSignature, hasDynamicStackAllocation); // Instructions MethodBodyWriter.Write(_metadata, instructions); // Exceptions SerializeExceptionRegions(body); return(offset); }
public void BlobEncoder_MethodSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.MethodSignature(); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); Assert.False(s.HasVarArgs); b.Clear(); s = e.MethodSignature( convention: SignatureCallingConvention.StdCall, genericParameterCount: 1234, isInstanceMethod: true); AssertEx.Equal(new byte[] { 0x32, 0x84, 0xD2 }, b.ToArray()); Assert.False(s.HasVarArgs); b.Clear(); s = e.MethodSignature( convention: SignatureCallingConvention.VarArgs, genericParameterCount: 1, isInstanceMethod: false); AssertEx.Equal(new byte[] { 0x15, 0x01 }, b.ToArray()); Assert.True(s.HasVarArgs); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: ushort.MaxValue + 1)); }
void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig) { 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; } signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); signatureBuilder.WriteCompressedInteger(sig.Length); // TODO Process custom modifiers in some way EncodeType(signatureBuilder, sig.ReturnType); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i]); } }
public void BlobEncoder_CustomAttributeSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); Assert.Same(b, e.Builder); FixedArgumentsEncoder fixedArgs; CustomAttributeNamedArgumentsEncoder namedArgs; e.CustomAttributeSignature(out fixedArgs, out namedArgs); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); Assert.Same(b, fixedArgs.Builder); Assert.Same(b, namedArgs.Builder); b.Clear(); e.CustomAttributeSignature( f => Assert.Same(b, f.Builder), n => Assert.Same(b, namedArgs.Builder)); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentNullException>(() => e.CustomAttributeSignature(null, n => { })); Assert.Throws <ArgumentNullException>(() => e.CustomAttributeSignature(f => { }, null)); }
void EncodeFieldSignature(BlobBuilder signatureBuilder, TypeDesc fieldType, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); signatureEncoder.FieldSignature(); EncodeType(signatureBuilder, fieldType, signatureDataEmitter); signatureDataEmitter.Pop(); }
public void BlobEncoder_FieldSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.FieldSignature(); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); Assert.Same(b, s.Builder); }
public void AllowUseOfAddGlobalMethod() { BlobBuilder noArgsNoReturnStaticMethodSig = new BlobBuilder(); BlobEncoder signatureEncoder = new BlobEncoder(noArgsNoReturnStaticMethodSig); signatureEncoder.MethodSignature(SignatureCallingConvention.Default, 0, false); noArgsNoReturnStaticMethodSig.WriteCompressedInteger(0); noArgsNoReturnStaticMethodSig.WriteByte((byte)SignatureTypeCode.Void); _noArgsVoidReturnStaticMethodSigHandle = _metadataBuilder.GetOrAddBlob(noArgsNoReturnStaticMethodSig); }
public void BlobEncoder_TypeSpecificationSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.TypeSpecificationSignature(); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, s.Builder); }
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); }
private EntityHandle ResolveMethodReference(MethodInfo method) { if (!IsReferencedType(method.DeclaringType)) { throw new ArgumentException( $"Method of a reference type is expected: {MetadataHelper.GetFriendlyName(method)}", nameof(method)); } // Constructed generic method? if (method.IsConstructedGenericMethod()) { // Already created? if (_methodSpecHandles.TryGetValue(method, out var handle)) { return(handle); } // Get the definition handle var definition = method.GetGenericMethodDefinition(); var definitionHandle = ResolveMethodReference(definition); // Create method spec encoder var enc = new BlobEncoder(new BlobBuilder()).MethodSpecificationSignature(definition.GetGenericArguments().Length); foreach (var a in method.GetGenericArguments()) { enc.AddArgument().FromSystemType(a, this); } // Add method spec var spec = Builder.AddMethodSpecification(definitionHandle, GetOrAddBlob(enc.Builder)); _methodSpecHandles.Add(method, spec); return(spec); } else { // Already created? if (_methodRefHandles.TryGetValue(method, out var handle)) { return(handle); } var typeRef = ResolveTypeReference(method.DeclaringType); var methodRef = Builder.AddMemberReference(typeRef, GetOrAddString(method.Name), GetMethodOrConstructorSignature(method)); _methodRefHandles.Add(method, methodRef); return(methodRef); } }
public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags)) { _metadataBuilder = new MetadataBuilder(); _ilBuilder = new BlobBuilder(); _methodBodyStream = new MethodBodyStreamEncoder(_ilBuilder); StringHandle assemblyNameHandle = _metadataBuilder.GetOrAddString(assemblyName.Name); if (assemblyName.CultureName != null) { throw new ArgumentException("assemblyName"); } if (assemblyName.GetPublicKeyToken() != null) { throw new ArgumentException("assemblyName"); } var mvid = _metadataBuilder.ReserveGuid(); _mvidFixup = mvid.Content; _metadataBuilder.AddModule(0, assemblyNameHandle, mvid.Handle, default(GuidHandle), default(GuidHandle)); _metadataBuilder.AddAssembly(assemblyNameHandle, assemblyName.Version ?? new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), flags, AssemblyHashAlgorithm.None); var canonAssemblyNameHandle = _metadataBuilder.GetOrAddString("System.Private.Canon"); var canonAssemblyRef = _metadataBuilder.AddAssemblyReference(canonAssemblyNameHandle, new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), (AssemblyFlags)0, default(BlobHandle)); var systemStringHandle = _metadataBuilder.GetOrAddString("System"); var canonStringHandle = _metadataBuilder.GetOrAddString("__Canon"); var canonTypeRef = _metadataBuilder.AddTypeReference(canonAssemblyRef, systemStringHandle, canonStringHandle); _typeRefs.Add(context.CanonType, canonTypeRef); _metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), _metadataBuilder.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); BlobBuilder noArgsNoReturnStaticMethodSig = new BlobBuilder(); BlobEncoder signatureEncoder = new BlobEncoder(noArgsNoReturnStaticMethodSig); signatureEncoder.MethodSignature(SignatureCallingConvention.Default, 0, false); noArgsNoReturnStaticMethodSig.WriteCompressedInteger(0); noArgsNoReturnStaticMethodSig.WriteByte((byte)SignatureTypeCode.Void); _noArgsVoidReturnStaticMethodSigHandle = _metadataBuilder.GetOrAddBlob(noArgsNoReturnStaticMethodSig); }
public void BlobEncoder_MethodSpecificationSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.MethodSpecificationSignature(genericArgumentCount: 0); AssertEx.Equal(new byte[] { 0x0A, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); e.MethodSpecificationSignature(genericArgumentCount: 1234); AssertEx.Equal(new byte[] { 0x0A, 0x84, 0xD2 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: ushort.MaxValue + 1)); }
public void BlobEncoder_PropertySignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.PropertySignature(); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); Assert.Same(b, s.Builder); Assert.False(s.HasVarArgs); b.Clear(); s = e.PropertySignature(isInstanceProperty: true); AssertEx.Equal(new byte[] { 0x28 }, b.ToArray()); Assert.False(s.HasVarArgs); b.Clear(); }
public void BlobEncoder_MethodSpecificationSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.MethodSpecificationSignature(genericArgumentCount: 0); AssertEx.Equal(new byte[] { 0x0A, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); e.MethodSpecificationSignature(genericArgumentCount: 1234); AssertEx.Equal(new byte[] { 0x0A, 0x84, 0xD2 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: -1)); Assert.Throws <ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: ushort.MaxValue + 1)); }
public void BlobEncoder_LocalVariableSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.LocalVariableSignature(variableCount: 0); AssertEx.Equal(new byte[] { 0x07, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.LocalVariableSignature(variableCount: 1000000); AssertEx.Equal(new byte[] { 0x07, 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.LocalVariableSignature(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => e.LocalVariableSignature(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
public void BlobEncoder_PermissionSetArguments() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.PermissionSetArguments(argumentCount: 0); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.PermissionSetArguments(argumentCount: 1000000); AssertEx.Equal(new byte[] { 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.PermissionSetArguments(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => e.PermissionSetArguments(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
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); EncodeType(signatureBuilder, sig.ReturnType, signatureDataEmitter); for (int i = 0; i < sig.Length; i++) { EncodeType(signatureBuilder, sig[i], signatureDataEmitter); } signatureDataEmitter.Pop(); }
public EntityHandle GetTypeHandle(Type type) { if (type.IsGenericType && !type.IsGenericTypeDefinition) { var typeSpecEncoder = new BlobEncoder(new BlobBuilder()).TypeSpecificationSignature(); typeSpecEncoder.FromSystemType(type, this); return(Builder.AddTypeSpecification(GetOrAddBlob(typeSpecEncoder.Builder))); } if (TryGetTypeDefinition(type, out var metadata)) { return(metadata.Handle); } if (IsReferencedType(type)) { return(ResolveTypeReference(type)); } throw new ArgumentException($"Type cannot be found: {MetadataHelper.GetFriendlyName(type)}", nameof(type)); }
public void EncodeMethodSignature(BlobBuilder methodSignatureBlob, MethodSignature signature) { BlobEncoder encoder = new BlobEncoder(methodSignatureBlob); MethodSignatureEncoder methodSigEncoder = encoder.MethodSignature( SignatureCallingConvention.Default, signature.GenericParameterCount, !signature.IsStatic); ReturnTypeEncoder returnTypeEncoder; ParametersEncoder parametersEncoder; methodSigEncoder.Parameters(signature.Length, out returnTypeEncoder, out parametersEncoder); // Return Type Sig EncodeTypeSignature(returnTypeEncoder.Type(), signature.ReturnType); // Parameter Types Sig for (int i = 0; i < signature.Length; i++) { EncodeTypeSignature(parametersEncoder.AddParameter().Type(), signature[i]); } }
private EntityHandle MakeMemberReferenceHandle(TypeSystemEntity methodOrField) { EntityHandle handle; if (!_memberRefOrSpecHandles.TryGetValue(methodOrField, out handle)) { MethodDesc method = methodOrField as MethodDesc; FieldDesc field = methodOrField as FieldDesc; TypeDesc owningType = (method != null ? method.OwningType : field.OwningType); string name = (method != null ? method.Name : field.Name); BlobHandle signature = method != null? MakeSignatureHandle(method.GetTypicalMethodDefinition()) : MakeSignatureHandle(field); handle = _metadataBuilder.AddMemberReference( MakeTypeRefOrSpecHandle(owningType), _metadataBuilder.GetOrAddString(name), signature); if (method != null && method.HasInstantiation && !method.IsTypicalMethodDefinition) { BlobEncoder methodSpecEncoder = new BlobEncoder(new BlobBuilder()); GenericTypeArgumentsEncoder argEncoder = methodSpecEncoder.MethodSpecificationSignature(method.Instantiation.Length); for (int i = 0; i < method.Instantiation.Length; i++) { SignatureTypeEncoder argTypeEncoder = argEncoder.AddArgument(); _signatureEmitter.EncodeTypeSignature(argTypeEncoder, method.Instantiation[i]); } handle = _metadataBuilder.AddMethodSpecification(handle, _metadataBuilder.GetOrAddBlob(methodSpecEncoder.Builder)); } _memberRefOrSpecHandles[methodOrField] = handle; } return(handle); }
private EntityHandle ResolveGenericTypeSpec(Type type) { if (!IsGenericTypeSpec(type)) { throw new ArgumentException($"Generic type spec is expected: {MetadataHelper.GetFriendlyName(type)}", nameof(type)); } if (_typeSpecHandles.TryGetValue(type, out var typeSpec)) { return(typeSpec); } var typeSpecEncoder = new BlobEncoder(new BlobBuilder()).TypeSpecificationSignature(); typeSpecEncoder.FromSystemType(type, this); var typeSpecHandle = Builder.AddTypeSpecification(GetOrAddBlob(typeSpecEncoder.Builder)); _typeSpecHandles.Add(type, typeSpecHandle); return(typeSpecHandle); }
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); } 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; BlobBuilder memberRefSig = new BlobBuilder(); EncodeMethodSignature(memberRefSig, sig); var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); methodHandle = _metadataBuilder.AddMemberReference(typeHandle, methodName, sigBlob); } _methodRefs.Add(method, methodHandle); return(methodHandle); }
public void BlobEncoder_Field() { var b = new BlobBuilder(); var e = new BlobEncoder(b); Assert.Same(b, e.Builder); var f = e.Field(); f.CustomModifiers() .AddModifier(MetadataTokens.TypeDefinitionHandle(1), isOptional: true) .AddModifier(MetadataTokens.TypeDefinitionHandle(2), isOptional: false); f.Type(isByRef: true).Object(); AssertEx.Equal(new byte[] { 0x06, 0x20, 0x04, 0x1F, 0x08, 0x10, 0x1C }, b.ToArray()); b.Clear(); f = e.Field(); f.CustomModifiers() .AddModifier(MetadataTokens.TypeDefinitionHandle(1), isOptional: true) .AddModifier(MetadataTokens.TypeDefinitionHandle(2), isOptional: false); f.Type().Int32(); AssertEx.Equal(new byte[] { 0x06, 0x20, 0x04, 0x1F, 0x08, 0x08 }, b.ToArray()); }
public MethodSignatureEncoder FunctionPointer(SignatureCallingConvention convention, FunctionPointerAttributes attributes, int genericParameterCount) { // Spec: // The EXPLICITTHIS (0x40) bit can be set only in signatures for function pointers. // If EXPLICITTHIS (0x40) in the signature is set, then HASTHIS (0x20) shall also be set. if (attributes != FunctionPointerAttributes.None && attributes != FunctionPointerAttributes.HasThis && attributes != FunctionPointerAttributes.HasExplicitThis) { throw new ArgumentException(nameof(attributes)); } Builder.WriteByte((byte)SignatureTypeCode.FunctionPointer); Builder.WriteByte(BlobEncoder.SignatureHeader(SignatureKind.Method, convention, (SignatureAttributes)attributes).RawValue); if (genericParameterCount != 0) { Builder.WriteCompressedInteger(genericParameterCount); } return(new MethodSignatureEncoder(Builder, isVarArg: convention == SignatureCallingConvention.VarArgs)); }
private BlobHandle MakeSignatureHandle(TypeSystemEntity methodOrField) { if (methodOrField is MethodDesc) { return(MakeSignatureHandle(((MethodDesc)methodOrField).Signature)); } else { BlobHandle handle; FieldDesc field = (FieldDesc)methodOrField; if (!_fieldSignatureHandles.TryGetValue(field, out handle)) { BlobBuilder metadataSignature = new BlobBuilder(); SignatureTypeEncoder fieldSigEncoder = new BlobEncoder(metadataSignature).FieldSignature(); _signatureEmitter.EncodeTypeSignature(fieldSigEncoder, field.FieldType); _fieldSignatureHandles[field] = handle = _metadataBuilder.GetOrAddBlob(metadataSignature); } return(handle); } }
public void BlobEncoder_CustomAttributeSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); Assert.Same(b, e.Builder); var parts = e.CustomAttributeSignature(); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); Assert.Same(b, parts.Item1.Builder); Assert.Same(b, parts.Item2.Builder); b.Clear(); e.CustomAttributeSignature( part => Assert.Same(b, part.Builder), part => Assert.Same(b, part.Builder)); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentNullException>(() => e.CustomAttributeSignature(null, _ => { })); Assert.Throws <ArgumentNullException>(() => e.CustomAttributeSignature(_ => { }, null)); }
public void BlobEncoder_PermissionSetArguments() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.PermissionSetArguments(argumentCount: 0); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.PermissionSetArguments(argumentCount: 1000000); AssertEx.Equal(new byte[] { 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.PermissionSetArguments(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.PermissionSetArguments(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
public void BlobEncoder_CustomAttributeSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); Assert.Same(b, e.Builder); var parts = e.CustomAttributeSignature(); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); Assert.Same(b, parts.Item1.Builder); Assert.Same(b, parts.Item2.Builder); b.Clear(); e.CustomAttributeSignature( part => Assert.Same(b, part.Builder), part => Assert.Same(b, part.Builder)); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(null, _ => { })); Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(_ => { }, null)); }
public BlobHandle GetMethodOrConstructorSignature(MethodBase methodBase) { // Method or Constructor? (must be one or the other) System.Diagnostics.Debug.Assert(methodBase is MethodInfo || methodBase is ConstructorInfo); if (methodBase.DeclaringType.IsConstructedGenericType) { // When calling methods on constructed generic types, the type is the constructed // type name, but the method info is the method from the open type definition. eg: // // callvirt instance void class System.Action`1<int32>::Invoke(!0) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ // constructed type here | // | // non constructed parameter type here ------+ // // ie: NOT this: // // callvirt instance void class System.Action`1<int32>::Invoke(int32) // ^^^^^ // wrong // // There doesn't seem to be a reflection API method to get the definition method. // Note: MethodInfo.GetGenericMethodDefinition won't work here because this is a // non-generic method in a generic type (as opposed to a generic method) // // Luckily both the original and the constructed type's method have the same meta // data token so we just go to the original generic definition and find the // method with the same token. // // TODO: What about generic method definitions in a generic type??? System.Diagnostics.Debug.Assert(!methodBase.IsGenericMethod); var definition = methodBase.DeclaringType.GetGenericTypeDefinition(); if (methodBase is MethodInfo) { methodBase = definition.GetMethods(AllMethods).Single(x => x.MetadataToken == methodBase.MetadataToken); } else { methodBase = definition.GetConstructors(AllMethods).Single(x => x.MetadataToken == methodBase.MetadataToken); } } // Get parameters var parameters = methodBase.GetParameters(); // Create method signature encoder var enc = new BlobEncoder(new BlobBuilder()) .MethodSignature( MetadataHelper.ConvertCallingConvention(methodBase.CallingConvention), genericParameterCount: (methodBase is MethodInfo) ? ((MethodInfo)methodBase).GetGenericArguments().Length : 0, isInstanceMethod: !methodBase.IsStatic); // Add return type and parameters enc.Parameters( parameters.Length, (retEnc) => { if (methodBase is MethodInfo) { retEnc.FromSystemType(((MethodInfo)methodBase).ReturnType, this); } else { retEnc.Void(); } }, (parEnc) => { foreach (var par in parameters) { if (par.ParameterType.IsByRef) { parEnc.AddParameter().Type(true).FromSystemType(par.ParameterType.GetElementType(), this); } else { parEnc.AddParameter().Type(false).FromSystemType(par.ParameterType, this); } } } ); // Get blob return(GetOrAddBlob(enc.Builder)); }
public void BlobEncoder_LocalVariableSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.LocalVariableSignature(variableCount: 0); AssertEx.Equal(new byte[] { 0x07, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.LocalVariableSignature(variableCount: 1000000); AssertEx.Equal(new byte[] { 0x07, 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.LocalVariableSignature(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.LocalVariableSignature(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
public void BlobEncoder_CustomAttributeSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); FixedArgumentsEncoder fixedArgs; CustomAttributeNamedArgumentsEncoder namedArgs; e.CustomAttributeSignature(out fixedArgs, out namedArgs); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); Assert.Same(b, fixedArgs.Builder); Assert.Same(b, namedArgs.Builder); b.Clear(); e.CustomAttributeSignature( f => Assert.Same(b, f.Builder), n => Assert.Same(b, namedArgs.Builder)); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(null, n => { })); Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(f => { }, null)); }