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); }
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); }
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()); }
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(); }
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()); }
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()); }