コード例 #1
0
        internal MethodDefinitionHandle CreateConstructor(ConstructorInfo constructorInfo)
        {
            if (_ctorDefHandles.TryGetValue(constructorInfo, out var constructorDef))
            {
                return(constructorDef);
            }

            var parameters = CreateParameters(constructorInfo.GetParameters());
            var bodyOffset = _ilBuilder.Count;

            var body = constructorInfo.GetMethodBody();

            if (body != null)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_ilBuilder, GetString, _typeHandles, _ctorRefHandles,
                                                                  _fieldHandles, _methodsHandles);

                // bodyOffset can be aligned during serialization. So, override the correct offset.
                bodyOffset = methodBodyWriter.AddMethodBody(constructorInfo);
            }

            var ctorDef = _metadataBuilder.AddMethodDefinition(
                constructorInfo.Attributes,
                constructorInfo.MethodImplementationFlags,
                GetString(constructorInfo.Name),
                GetConstructorSignature(constructorInfo),
                bodyOffset,
                parameters);

            _ctorDefHandles.Add(constructorInfo, ctorDef);

            return(ctorDef);
        }
コード例 #2
0
        private MethodDefinitionHandle GetOrCreateMethod(MethodInfo methodInfo)
        {
            if (_methodsHandles.ContainsKey(methodInfo))
            {
                return(_methodsHandles[methodInfo]);
            }

            var offset = _ilBuilder.Count; // take an offset
            var body   = methodInfo.GetMethodBody();

            // If body exists, we write it in IL body stream
            if (body != null)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_ilBuilder, GetString, _typeHandles, _ctorRefHandles,
                                                                  _fieldHandles, _methodsHandles);

                // offset can be aligned during serialization. So, override the correct offset.
                offset = methodBodyWriter.AddMethodBody(methodInfo);
            }

            var signature  = GetMethodSignature(methodInfo);
            var parameters = CreateParameters(methodInfo.GetParameters());

            var handle = _metadataBuilder.AddMethodDefinition(
                methodInfo.Attributes,
                methodInfo.MethodImplementationFlags,
                GetString(methodInfo.Name),
                signature,
                offset,
                parameters);


            if (body != null && body.LocalVariables.Count > 0)
            {
                _metadataBuilder.AddStandaloneSignature
                    (GetBlob(
                        BuildSignature(x =>
                {
                    var sig = x.LocalVariableSignature(body.LocalVariables.Count);
                    foreach (var vrb in body.LocalVariables)
                    {
                        sig.AddVariable().Type(
                            vrb.LocalType.IsByRef,
                            vrb.IsPinned)
                        .FromSystemType(vrb.LocalType, this);
                    }
                })));
            }

            /*
             * FieldList and MethodList described in ECMA 335, page 270
             */

            _methodsHandles.Add(methodInfo, handle);

            CreateCustomAttributes(handle, methodInfo.GetCustomAttributesData());
            return(handle);
        }
コード例 #3
0
        private void CreateMethod(MethodInfo method)
        {
            if (!_metadata.TryGetMethodDefinition(method, out var metadata))
            {
                ThrowMetadataIsNotReserved("Method", method);
            }

            EnsureMetadataWasNotEmitted(metadata, method);

            var body = method.GetMethodBody();

            var localVariablesSignature = default(StandaloneSignatureHandle);

            if (body != null && body.LocalVariables.Count > 0)
            {
                localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob(
                                                                                       MetadataHelper.BuildSignature(x =>
                {
                    var sig = x.LocalVariableSignature(body.LocalVariables.Count);
                    foreach (var vrb in body.LocalVariables)
                    {
                        sig.AddVariable().Type(
                            vrb.LocalType.IsByRef,
                            vrb.IsPinned)
                        .FromSystemType(vrb.LocalType, _metadata);
                    }
                })));
            }

            var offset = _metadata.ILBuilder.Count; // take an offset

            // If body exists, we write it in IL body stream
            if (body != null)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_metadata);

                // offset can be aligned during serialization. So, override the correct offset.
                offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature);
            }

            var parameters = CreateParameters(method.GetParameters());

            var handle = _metadata.Builder.AddMethodDefinition(
                method.Attributes,
                method.MethodImplementationFlags,
                _metadata.GetOrAddString(method.Name),
                _metadata.GetMethodSignature(method),
                offset,
                parameters);

            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();

            CreateCustomAttributes(handle, method.GetCustomAttributesData());
        }
コード例 #4
0
        private void CreateConstructor(ConstructorInfo ctor)
        {
            if (!_metadata.TryGetConstructorDefinition(ctor, out var metadata))
            {
                ThrowMetadataIsNotReserved("Constructor", ctor);
            }

            EnsureMetadataWasNotEmitted(metadata, ctor);

            var body = ctor.GetMethodBody();

            var localVariablesSignature = default(StandaloneSignatureHandle);

            if (body != null && body.LocalVariables.Count > 0)
            {
                localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob(
                                                                                       MetadataHelper.BuildSignature(x =>
                {
                    var sig = x.LocalVariableSignature(body.LocalVariables.Count);
                    foreach (var vrb in body.LocalVariables)
                    {
                        sig.AddVariable().Type(
                            vrb.LocalType.IsByRef,
                            vrb.IsPinned)
                        .FromSystemType(vrb.LocalType, _metadata);
                    }
                })));
            }

            var bodyOffset = _metadata.ILBuilder.Count;

            if (body != null)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_metadata);

                // bodyOffset can be aligned during serialization. So, override the correct offset.
                bodyOffset = methodBodyWriter.AddMethodBody(ctor, localVariablesSignature);
            }

            var parameters = CreateParameters(ctor.GetParameters());

            var handle = _metadata.Builder.AddMethodDefinition(
                ctor.Attributes,
                ctor.MethodImplementationFlags,
                _metadata.GetOrAddString(ctor.Name),
                _metadata.GetConstructorSignature(ctor),
                bodyOffset,
                parameters);

            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();
        }
コード例 #5
0
        private void CreateMethod(MethodInfo method, List <DelayedWrite> genericParams)
        {
            if (!_metadata.TryGetMethodDefinition(method, out var metadata))
            {
                ThrowMetadataIsNotReserved("Method", method);
            }

            EnsureMetadataWasNotEmitted(metadata, method);

            var body = method.GetMethodBody();

            var localVariablesSignature = default(StandaloneSignatureHandle);

            if (body != null && body.LocalVariables.Count > 0)
            {
                localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob(
                                                                                       MetadataHelper.BuildSignature(x =>
                {
                    x.LocalVariableSignature(body.LocalVariables.Count).AddRange(body.LocalVariables, _metadata);
                })));
            }

            var offset = -1;

            // If body exists, we write it in IL body stream
            if (body != null && !method.IsAbstract)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_metadata);

                // offset can be aligned during serialization. So, override the correct offset.
                offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature);
            }

            var parameters = CreateParameters(method.GetParameters());

            var handle = _metadata.Builder.AddMethodDefinition(
                method.Attributes,
                method.MethodImplementationFlags,
                _metadata.GetOrAddString(method.Name),
                _metadata.GetMethodOrConstructorSignature(method),
                offset,
                parameters);

            // The generation of interface method overrides has been moved to
            // AssemblyGenerator.DeclareInterfacesAndCreateInterfaceMap in
            // AssemblyGenerator.Types.cs.

            // Add generic parameters
            if (method.IsGenericMethodDefinition)
            {
                int index = 0;
                foreach (var arg in method.GetGenericArguments())
                {
                    genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () =>
                    {
                        // Add the argument
                        var gaHandle = _metadata.Builder.AddGenericParameter(handle, arg.GenericParameterAttributes, _metadata.GetOrAddString(arg.Name), index++);

                        // Add it's constraints
                        foreach (var constraint in arg.GetGenericParameterConstraints())
                        {
                            _metadata.Builder.AddGenericParameterConstraint(gaHandle, _metadata.GetTypeHandle(constraint));
                        }
                    }));
                }
            }
            else if (method.Attributes.HasFlag(MethodAttributes.PinvokeImpl))
            {
                ProcessPInvokeMapData(
                    method,
                    out string libraryName,
                    out string entryName,
                    out MethodImportAttributes attrs);

                var libraryNameHandle = _metadata.GetOrAddString(libraryName);
                var moduleRefHandle   = _metadata.Builder.AddModuleReference(libraryNameHandle);
                var entryNameHandle   = _metadata.GetOrAddString(entryName);

                // Add the ImplMap entry for the P/Invoke
                _metadata.Builder.AddMethodImport(
                    handle,
                    attrs,
                    entryNameHandle,
                    moduleRefHandle);
            }

            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();

            CreateCustomAttributes(handle, method.GetCustomAttributesData());
        }
コード例 #6
0
        private void CreateMethod(MethodInfo method, List <DelayedWrite> genericParams)
        {
            if (!_metadata.TryGetMethodDefinition(method, out var metadata))
            {
                ThrowMetadataIsNotReserved("Method", method);
            }

            EnsureMetadataWasNotEmitted(metadata, method);

            var body = method.GetMethodBody();

            var localVariablesSignature = default(StandaloneSignatureHandle);

            if (body != null && body.LocalVariables.Count > 0)
            {
                localVariablesSignature = _metadata.Builder.AddStandaloneSignature(_metadata.GetOrAddBlob(
                                                                                       MetadataHelper.BuildSignature(x =>
                {
                    x.LocalVariableSignature(body.LocalVariables.Count).AddRange(body.LocalVariables, _metadata);
                })));
            }

            var offset = -1;

            // If body exists, we write it in IL body stream
            if (body != null && !method.IsAbstract)
            {
                var methodBodyWriter = new MethodBodyStreamWriter(_metadata);

                // offset can be aligned during serialization. So, override the correct offset.
                offset = methodBodyWriter.AddMethodBody(method, localVariablesSignature);
            }

            var parameters = CreateParameters(method.GetParameters());

            var handle = _metadata.Builder.AddMethodDefinition(
                method.Attributes,
                method.MethodImplementationFlags,
                _metadata.GetOrAddString(method.Name),
                _metadata.GetMethodOrConstructorSignature(method),
                offset,
                parameters);

            // Explicit interface implementations need to be marked with method implementation
            // (This is the equivalent of .Override in msil)
            if (method.IsPrivate)
            {
                // Go through all the implemented interfaces and all their methods
                // looking for methods that this method implements and mark accordingly.

                // NB: This is not super efficient.  Should probably create a map somewhere
                //     for faster lookup, but this will do for now.

                var type = method.DeclaringType;
                foreach (var itf in type.GetInterfaces())
                {
                    var itfMap = type.GetInterfaceMap(itf);
                    for (int i = 0; i < itfMap.TargetMethods.Length; i++)
                    {
                        var m = itfMap.TargetMethods[i];
                        if (m == method)
                        {
                            var itfImpl = itfMap.InterfaceMethods[i];
                            _metadata.Builder.AddMethodImplementation((TypeDefinitionHandle)_metadata.GetTypeHandle(method.DeclaringType), handle, _metadata.GetMethodHandle(itfImpl));
                        }
                    }
                }
            }

            // Add generic parameters
            if (method.IsGenericMethodDefinition)
            {
                int index = 0;
                foreach (var arg in method.GetGenericArguments())
                {
                    genericParams.Add(new DelayedWrite(CodedIndex.TypeOrMethodDef(handle), () =>
                    {
                        // Add the argument
                        var gaHandle = _metadata.Builder.AddGenericParameter(handle, arg.GenericParameterAttributes, _metadata.GetOrAddString(arg.Name), index++);

                        // Add it's constraints
                        foreach (var constraint in arg.GetGenericParameterConstraints())
                        {
                            _metadata.Builder.AddGenericParameterConstraint(gaHandle, _metadata.GetTypeHandle(constraint));
                        }
                    }));
                }
            }

            VerifyEmittedHandle(metadata, handle);
            metadata.MarkAsEmitted();

            CreateCustomAttributes(handle, method.GetCustomAttributesData());
        }