コード例 #1
0
        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);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        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));
            }
        }
コード例 #4
0
        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,
コード例 #5
0
        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);
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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]);
            }
        }
コード例 #8
0
        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));
        }
コード例 #9
0
        void EncodeFieldSignature(BlobBuilder signatureBuilder, TypeDesc fieldType, EmbeddedSignatureDataEmitter signatureDataEmitter)
        {
            signatureDataEmitter.Push();
            BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder);

            signatureEncoder.FieldSignature();
            EncodeType(signatureBuilder, fieldType, signatureDataEmitter);
            signatureDataEmitter.Pop();
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
            }
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        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));
        }
コード例 #18
0
        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();
        }
コード例 #19
0
        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));
        }
コード例 #20
0
        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));
        }
コード例 #21
0
        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));
        }
コード例 #22
0
        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();
        }
コード例 #23
0
        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));
        }
コード例 #24
0
ファイル: EcmaSignatureEncoder.cs プロジェクト: z77ma/runtime
        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]);
            }
        }
コード例 #25
0
        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);
        }
コード例 #26
0
        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);
        }
コード例 #27
0
        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);
        }
コード例 #28
0
        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());
        }
コード例 #29
0
        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));
        }
コード例 #30
0
        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);
            }
        }
コード例 #31
0
        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));
        }
コード例 #32
0
        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));
        }
コード例 #33
0
        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);
        }
コード例 #34
0
ファイル: BlobEncodersTests.cs プロジェクト: sepidehMS/corefx
        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));
        }
コード例 #35
0
        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();
        }
コード例 #36
0
        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));
        }
コード例 #37
0
        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));
        }
コード例 #38
0
        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));
        }