Пример #1
0
        private MethodSignature HandleMethodSignature(Cts.MethodSignature signature)
        {
            List <ParameterTypeSignature> parameters;

            if (signature.Length > 0)
            {
                parameters = new List <ParameterTypeSignature>(signature.Length);
                for (int i = 0; i < signature.Length; i++)
                {
                    parameters.Add(HandleParameterTypeSignature(signature[i]));
                }
            }
            else
            {
                parameters = null;
            }

            return(new MethodSignature
            {
                // TODO: CallingConvention
                GenericParameterCount = signature.GenericParameterCount,
                Parameters = parameters,
                ReturnType = new ReturnTypeSignature
                {
                    // TODO: CustomModifiers
                    Type = HandleType(signature.ReturnType)
                },
                // TODO-NICE: VarArgParameters
            });
        }
Пример #2
0
        public static MethodIL EmitIL(MethodDesc target)
        {
            Debug.Assert(target.Name == "Call");
            Debug.Assert(target.Signature.Length > 0
                && target.Signature[0] == target.Context.GetWellKnownType(WellKnownType.IntPtr));

            ILEmitter emitter = new ILEmitter();
            var codeStream = emitter.NewCodeStream();

            // Load all the arguments except the first one (IntPtr address)
            for (int i = 1; i < target.Signature.Length; i++)
            {
                codeStream.EmitLdArg(i);
            }

            // now load IntPtr address
            codeStream.EmitLdArg(0);

            // Create a signature for the calli by copying the signature of the containing method
            // while skipping the first argument
            MethodSignature template = target.Signature;
            TypeDesc returnType = template.ReturnType;
            TypeDesc[] parameters = new TypeDesc[template.Length - 1];
            for (int i = 1; i < template.Length; i++)
            {
                parameters[i - 1] = template[i];
            }

            var signature = new MethodSignature(template.Flags, 0, returnType, parameters);

            codeStream.Emit(ILOpcode.calli, emitter.NewToken(signature));
            codeStream.Emit(ILOpcode.ret);

            return emitter.Link();
        }
Пример #3
0
        public void TestMethodLookup()
        {
            MetadataType t = _testModule.GetType("GenericTypes", "GenericClass`1").MakeInstantiatedType(_context.GetWellKnownType(WellKnownType.Int32));

            MethodSignature sig = new MethodSignature(MethodSignatureFlags.None, 0, t.Instantiation[0], new TypeDesc[0] { });
            MethodDesc fooMethod = t.GetMethod("Foo", sig);
            Assert.NotNull(fooMethod);
        }
Пример #4
0
        private MethodSignature InitializeSignature()
        {
            var metadataReader = MetadataReader;
            BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetMethodDefinition(_handle).Signature);

            EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader);
            var signature = parser.ParseMethodSignature();
            return (_signature = signature);
        }
Пример #5
0
        private bool IsBlocked(Cts.TypeDesc type)
        {
            switch (type.Category)
            {
            case Cts.TypeFlags.SzArray:
            case Cts.TypeFlags.Array:
            case Cts.TypeFlags.Pointer:
            case Cts.TypeFlags.ByRef:
                return(IsBlocked(((Cts.ParameterizedType)type).ParameterType));

            case Cts.TypeFlags.SignatureMethodVariable:
            case Cts.TypeFlags.SignatureTypeVariable:
                return(false);

            case Cts.TypeFlags.FunctionPointer:
            {
                Cts.MethodSignature pointerSignature = ((Cts.FunctionPointerType)type).Signature;
                if (IsBlocked(pointerSignature.ReturnType))
                {
                    return(true);
                }

                for (int i = 0; i < pointerSignature.Length; i++)
                {
                    if (IsBlocked(pointerSignature[i]))
                    {
                        return(true);
                    }
                }

                return(false);
            }

            default:
                Debug.Assert(type.IsDefType);

                if (!type.IsTypeDefinition)
                {
                    if (IsBlocked(type.GetTypeDefinition()))
                    {
                        return(true);
                    }

                    foreach (var arg in type.Instantiation)
                    {
                        if (IsBlocked(arg))
                        {
                            return(true);
                        }
                    }

                    return(false);
                }

                return(_policy.IsBlocked((Cts.MetadataType)type));
            }
        }
Пример #6
0
        /// <summary>
        /// Retrieves a method on <paramref name="type"/> that is well known to the compiler.
        /// Throws an exception if the method doesn't exist.
        /// </summary>
        public static MethodDesc GetKnownMethod(this TypeDesc type, string name, MethodSignature signature)
        {
            MethodDesc method = type.GetMethod(name, signature);
            if (method == null)
            {
                throw new InvalidOperationException(String.Format("Expected method '{0}' not found on type '{1}'", name, type));
            }

            return method;
        }
Пример #7
0
        private CallingConventions GetSignatureCallingConvention(Cts.MethodSignature signature)
        {
            CallingConventions callingConvention = CallingConventions.Standard;

            if ((signature.Flags & Cts.MethodSignatureFlags.Static) == 0)
            {
                callingConvention = CallingConventions.HasThis;
            }
            // TODO: additional calling convention flags like stdcall / cdecl etc.
            return(callingConvention);
        }
Пример #8
0
        public static MethodIL EmitIL(MethodDesc target)
        {
            Debug.Assert(target.Name == "Call");
            Debug.Assert(target.Signature.Length > 0
                && target.Signature[0] == target.Context.GetWellKnownType(WellKnownType.IntPtr));

            ILEmitter emitter = new ILEmitter();
            var codeStream = emitter.NewCodeStream();

            // Load all the arguments except the first one (IntPtr address)
            for (int i = 1; i < target.Signature.Length; i++)
            {
                codeStream.EmitLdArg(i);
            }

            // now load IntPtr address
            codeStream.EmitLdArg(0);

            // Create a signature for the calli by copying the signature of the containing method
            // while skipping the first argument
            MethodSignature template = target.Signature;
            TypeDesc returnType = template.ReturnType;
            TypeDesc[] parameters = new TypeDesc[template.Length - 1];
            for (int i = 1; i < template.Length; i++)
            {
                parameters[i - 1] = template[i];
            }

            var signature = new MethodSignature(template.Flags, 0, returnType, parameters);

            bool useTransformedCalli = true;

            if ((signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) != 0)
            {
                // Fat function pointer only ever exist for managed targets.
                useTransformedCalli = false;
            }

            if (((MetadataType)target.OwningType).Name == "RawCalliHelper")
            {
                // RawCalliHelper doesn't need the transform.
                useTransformedCalli = false;
            }

            if (useTransformedCalli)
                EmitTransformedCalli(emitter, codeStream, signature);
            else
                codeStream.Emit(ILOpcode.calli, emitter.NewToken(signature));
            
            codeStream.Emit(ILOpcode.ret);

            return emitter.Link(target);
        }
        public void TestVirtualDispatchOnGenericType()
        {
            // Verifies that virtual dispatch to a non-generic method on a generic instantiation works
            DefType objectType = _context.GetWellKnownType(WellKnownType.Object);
            MethodSignature toStringSig = new MethodSignature(MethodSignatureFlags.None, 0, _stringType, Array.Empty<TypeDesc>());
            MethodDesc objectToString = objectType.GetMethod("ToString", toStringSig);
            Assert.NotNull(objectToString);
            MetadataType openTestType = _testModule.GetType("VirtualFunctionOverride", "SimpleGeneric`1");
            InstantiatedType testInstance = openTestType.MakeInstantiatedType(new Instantiation(new TypeDesc[] { objectType }));
            MethodDesc targetOnInstance = testInstance.GetMethod("ToString", toStringSig);

            MethodDesc targetMethod = VirtualFunctionResolution.FindVirtualFunctionTargetMethodOnObjectType(objectToString, testInstance);
            Assert.Equal(targetOnInstance, targetMethod);        
        }
Пример #10
0
        /// <summary>
        /// NEWOBJ operation on String type is actually a call to a static method that returns a String
        /// instance (i.e. there's an explicit call to the runtime allocator from the static method body).
        /// This method returns the alloc+init helper corresponding to a given string constructor.
        /// </summary>
        public static MethodDesc GetStringInitializer(this MethodDesc constructorMethod)
        {
            Debug.Assert(constructorMethod.IsConstructor);
            Debug.Assert(constructorMethod.OwningType.IsString);

            var constructorSignature = constructorMethod.Signature;

            // There's an extra (useless) Object as the first arg to match RyuJIT expectations.
            var parameters = new TypeDesc[constructorSignature.Length + 1];
            parameters[0] = constructorMethod.Context.GetWellKnownType(WellKnownType.Object);
            for (int i = 0; i < constructorSignature.Length; i++)
                parameters[i + 1] = constructorSignature[i];

            MethodSignature sig = new MethodSignature(
                MethodSignatureFlags.Static, 0, constructorMethod.OwningType, parameters);

            MethodDesc result = constructorMethod.OwningType.GetKnownMethod("Ctor", sig);
            return result;
        }
Пример #11
0
        public static MethodIL EmitIL(MethodDesc target)
        {
            Debug.Assert(target.Name == "CompareExchange" || target.Name == "Exchange");

            //
            // Find non-generic method to forward the generic method to.
            //

            int parameterCount = target.Signature.Length;
            Debug.Assert(parameterCount == 3 || parameterCount == 2);

            var objectType = target.Context.GetWellKnownType(WellKnownType.Object);

            var parameters = new TypeDesc[parameterCount];
            parameters[0] = objectType.MakeByRefType();
            for (int i = 1; i < parameters.Length; i++)
                parameters[i] = objectType;

            MethodSignature nonGenericSignature = new MethodSignature(MethodSignatureFlags.Static, 0, objectType, parameters);

            MethodDesc nonGenericMethod = target.OwningType.GetMethod(target.Name, nonGenericSignature);

            // TODO: Better exception type. Should be: "CoreLib doesn't have a required thing in it".
            if (nonGenericMethod == null)
                throw new NotImplementedException();

            //
            // Emit the forwarder
            //

            ILEmitter emitter = new ILEmitter();
            var codeStream = emitter.NewCodeStream();

            // Reload all arguments
            for (int i = 0; i < parameterCount; i++)
                codeStream.EmitLdArg(i);

            codeStream.Emit(ILOpcode.call, emitter.NewToken(nonGenericMethod));
            codeStream.Emit(ILOpcode.ret);

            return emitter.Link();
        }
Пример #12
0
        public void TestStandaloneSignatureGeneration()
        {
            var transformResult = MetadataTransform.Run(new SingleFileMetadataPolicy(), new[] { _systemModule });

            var stringRecord = transformResult.GetTransformedTypeDefinition(
                (Cts.MetadataType)_context.GetWellKnownType(Cts.WellKnownType.String));
            var singleRecord = transformResult.GetTransformedTypeDefinition(
                (Cts.MetadataType)_context.GetWellKnownType(Cts.WellKnownType.Single));

            var sig = new Cts.MethodSignature(
                0, 0, _context.GetWellKnownType(Cts.WellKnownType.String),
                new[] { _context.GetWellKnownType(Cts.WellKnownType.Single) });

            var sigRecord = transformResult.Transform.HandleMethodSignature(sig);

            // Verify the signature is connected to the existing transformResult world
            Assert.Same(stringRecord, sigRecord.ReturnType.Type);
            Assert.Equal(1, sigRecord.Parameters.Count);
            Assert.Same(singleRecord, sigRecord.Parameters[0].Type);
        }
Пример #13
0
        public void TestStandaloneSignatureGeneration()
        {
            var transformResult = MetadataTransform.Run(new SingleFileMetadataPolicy(), new[] { _systemModule });

            var stringRecord = transformResult.GetTransformedTypeDefinition(
                (Cts.MetadataType)_context.GetWellKnownType(Cts.WellKnownType.String));
            var singleRecord = transformResult.GetTransformedTypeDefinition(
                (Cts.MetadataType)_context.GetWellKnownType(Cts.WellKnownType.Single));

            var sig = new Cts.MethodSignature(
                0, 0, _context.GetWellKnownType(Cts.WellKnownType.String),
                new[] { _context.GetWellKnownType(Cts.WellKnownType.Single) });

            var sigRecord = transformResult.Transform.HandleMethodSignature(sig);

            // Verify the signature is connected to the existing transformResult world
            Assert.Same(stringRecord, sigRecord.ReturnType);
            Assert.Equal(1, sigRecord.Parameters.Count);
            Assert.Same(singleRecord, sigRecord.Parameters[0]);
        }
Пример #14
0
        public override MethodSignature HandleMethodSignature(Cts.MethodSignature signature)
        {
            // TODO: if Cts.MethodSignature implements Equals/GetHashCode, we could enable pooling here.

            var result = new MethodSignature
            {
                CallingConvention     = GetSignatureCallingConvention(signature),
                GenericParameterCount = signature.GenericParameterCount,
                ReturnType            = HandleType(signature.ReturnType),
                // TODO-NICE: VarArgParameters
            };

            result.Parameters.Capacity = signature.Length;
            for (int i = 0; i < signature.Length; i++)
            {
                result.Parameters.Add(HandleType(signature[i]));
            }

            return(result);
        }
Пример #15
0
        /// <summary>
        /// NEWOBJ operation on String type is actually a call to a static method that returs a String
        /// instance (i.e. there's an explict call to the runtime allocator from the static method body).
        /// This method returns the alloc+init helper corresponding to a given string constructor.
        /// </summary>
        public static MethodDesc GetStringInitializer(MethodDesc constructorMethod)
        {
            Debug.Assert(constructorMethod.IsConstructor);
            Debug.Assert(constructorMethod.OwningType.IsString);

            // There's an extra (useless) Object as the first arg to match RyuJIT expectations.
            var parameters = new TypeDesc[constructorMethod.Signature.Length + 1];
            parameters[0] = constructorMethod.Context.GetWellKnownType(WellKnownType.Object);
            for (int i = 0; i < constructorMethod.Signature.Length; i++)
                parameters[i + 1] = constructorMethod.Signature[i];

            MethodSignature sig = new MethodSignature(
                MethodSignatureFlags.Static, 0, constructorMethod.OwningType, parameters);

            MethodDesc result = constructorMethod.OwningType.GetMethod("Ctor", sig);

            // TODO: Better exception type. Should be: "CoreLib doesn't have a required thing in it".
            if (result == null)
                throw new NotImplementedException();

            return result;
        }
Пример #16
0
        public bool Equals(MethodSignature otherSignature)
        {
            // TODO: Generics, etc.
            if (this._flags != otherSignature._flags)
                return false;

            if (this._genericParameterCount != otherSignature._genericParameterCount)
                return false;

            if (this._returnType != otherSignature._returnType)
                return false;

            if (this._parameters.Length != otherSignature._parameters.Length)
                return false;

            for (int i = 0; i < this._parameters.Length; i++)
            {
                if (this._parameters[i] != otherSignature._parameters[i])
                    return false;
            }

            return true;
        }
Пример #17
0
        public static MethodIL EmitIL(MethodDesc method)
        {
            if (!RequiresMarshalling(method))
                return null;

            try
            {
                return new PInvokeMarshallingILEmitter(method).EmitIL();
            }
            catch (NotSupportedException)
            {
                ILEmitter emitter = new ILEmitter();
                string message = "Method '" + method.ToString() +
                    "' requires non-trivial marshalling that is not yet supported by this compiler.";

                TypeSystemContext context = method.Context;
                MethodSignature ctorSignature = new MethodSignature(0, 0, context.GetWellKnownType(WellKnownType.Void),
                    new TypeDesc[] { context.GetWellKnownType(WellKnownType.String) });
                MethodDesc exceptionCtor = method.Context.GetWellKnownType(WellKnownType.Exception).GetKnownMethod(".ctor", ctorSignature);

                ILCodeStream codeStream = emitter.NewCodeStream();
                codeStream.Emit(ILOpcode.ldstr, emitter.NewToken(message));
                codeStream.Emit(ILOpcode.newobj, emitter.NewToken(exceptionCtor));
                codeStream.Emit(ILOpcode.throw_);
                codeStream.Emit(ILOpcode.ret);

                return emitter.Link();
            }
        }
Пример #18
0
        /// <summary>
        /// Gets calling conventions for a standalone ('calli') method signature.
        /// </summary>
        public static UnmanagedCallingConventions GetStandaloneMethodSignatureCallingConventions(this MethodSignature signature)
        {
            // If calling convention is anything but 'unmanaged', or there's no modifiers, we can bitcast to our enum and we're done.
            MethodSignatureFlags unmanagedCallconv = signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask;

            if (unmanagedCallconv != MethodSignatureFlags.UnmanagedCallingConvention)
            {
                Debug.Assert((int)MethodSignatureFlags.UnmanagedCallingConventionCdecl == (int)UnmanagedCallingConventions.Cdecl &&
                             (int)MethodSignatureFlags.UnmanagedCallingConventionStdCall == (int)UnmanagedCallingConventions.Stdcall &&
                             (int)MethodSignatureFlags.UnmanagedCallingConventionThisCall == (int)UnmanagedCallingConventions.Thiscall);
                Debug.Assert(unmanagedCallconv != 0);
                return((UnmanagedCallingConventions)unmanagedCallconv);
            }

            // If calling convention is 'unmanaged', there might be more metadata in the custom modifiers.
            UnmanagedCallingConventions result = 0;

            if (signature.HasEmbeddedSignatureData)
            {
                foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData())
                {
                    if (data.kind != EmbeddedSignatureDataKind.OptionalCustomModifier)
                    {
                        continue;
                    }

                    // We only care about the modifiers for the return type. These will be at the start of
                    // the signature, so will be first in the array of embedded signature data.
                    if (data.index != MethodSignature.IndexOfCustomModifiersOnReturnType)
                    {
                        break;
                    }

                    if (data.type is not MetadataType mdType)
                    {
                        continue;
                    }

                    result = AccumulateCallingConventions(result, mdType);
                }
            }

            // If we haven't found a calling convention in the modifiers, the calling convention is 'unmanaged'.
            if ((result & UnmanagedCallingConventions.CallingConventionMask) == 0)
            {
                result |= GetPlatformDefaultUnmanagedCallingConvention(signature.Context);
            }

            return(result);
        }
Пример #19
0
 public int Compare(MethodSignature x, MethodSignature y)
 {
     return(x.CompareTo(y, this));
 }
Пример #20
0
 public MissingMethodException(TypeDesc owningType, string methodName, MethodSignature signature)
     : this(ExceptionStringID.MissingField, Format.Method(owningType, methodName, signature))
 {
 }
Пример #21
0
 internal FunctionPointerType(MethodSignature signature)
 {
     _signature = signature;
 }
Пример #22
0
 /// <summary>
 /// Gets a named method on the type. This method only looks at methods defined
 /// in type's metadata. The <paramref name="signature"/> parameter can be null.
 /// If signature is not specified and there are multiple matches, the first one
 /// is returned. Returns null if method not found.
 /// </summary>
 // TODO: Substitutions, generics, modopts, ...
 public virtual MethodDesc GetMethod(string name, MethodSignature signature)
 {
     foreach (var method in GetMethods())
     {
         if (method.Name == name)
         {
             if (signature == null || signature.Equals(method.Signature))
                 return method;
         }
     }
     return null;
 }
Пример #23
0
        public MethodSignatureBuilder(MethodSignature template)
        {
            _template = template;

            _flags = template._flags;
            _genericParameterCount = template._genericParameterCount;
            _returnType = template._returnType;
            _parameters = template._parameters;
        }
Пример #24
0
        private bool Equals(MethodSignature otherSignature, bool allowCovariantReturn)
        {
            // TODO: Generics, etc.
            if (this._flags != otherSignature._flags)
            {
                return(false);
            }

            if (this._genericParameterCount != otherSignature._genericParameterCount)
            {
                return(false);
            }

            if (this._returnType != otherSignature._returnType)
            {
                if (!allowCovariantReturn)
                {
                    return(false);
                }

                if (!otherSignature._returnType.IsCompatibleWith(this._returnType))
                {
                    return(false);
                }
            }

            if (this._parameters.Length != otherSignature._parameters.Length)
            {
                return(false);
            }

            for (int i = 0; i < this._parameters.Length; i++)
            {
                if (this._parameters[i] != otherSignature._parameters[i])
                {
                    return(false);
                }
            }

            if (this._embeddedSignatureData == null && otherSignature._embeddedSignatureData == null)
            {
                return(true);
            }

            if (this._embeddedSignatureData != null && otherSignature._embeddedSignatureData != null)
            {
                if (this._embeddedSignatureData.Length != otherSignature._embeddedSignatureData.Length)
                {
                    return(false);
                }

                for (int i = 0; i < this._embeddedSignatureData.Length; i++)
                {
                    if (this._embeddedSignatureData[i].index != otherSignature._embeddedSignatureData[i].index)
                    {
                        return(false);
                    }
                    if (this._embeddedSignatureData[i].kind != otherSignature._embeddedSignatureData[i].kind)
                    {
                        return(false);
                    }
                    if (this._embeddedSignatureData[i].type != otherSignature._embeddedSignatureData[i].type)
                    {
                        return(false);
                    }
                }

                return(true);
            }

            return(false);
        }
Пример #25
0
 public bool EqualsWithCovariantReturnType(MethodSignature otherSignature)
 {
     return(Equals(otherSignature, allowCovariantReturn: true));
 }
 /// <summary>
 /// Retrieves an existing <see cref="MethodSignature"/> record representing the specified signature
 /// in the metadata writer object model, or creates a new one.
 /// </summary>
 public abstract MethodSignature HandleMethodSignature(Cts.MethodSignature signature);
Пример #27
0
 public FunctionPointerType GetFunctionPointerType(MethodSignature signature)
 {
     return(_functionPointerTypes.GetOrCreateValue(signature));
 }
Пример #28
0
 /// <summary>
 /// Gets a named method on the type. This method only looks at methods defined
 /// in type's metadata. The <paramref name="signature"/> parameter can be null.
 /// If signature is not specified and there are multiple matches, the first one
 /// is returned. Returns null if method not found.
 /// </summary>
 public MethodDesc GetMethod(string name, MethodSignature signature)
 {
     return(GetMethod(name, signature, default(Instantiation)));
 }
Пример #29
0
        /// <summary>
        /// Replace some of the types in a type's construction with a new set of types. This function does not
        /// support any situation where there is an instantiated generic that is not represented by an
        /// InstantiatedType. Does not replace the open generics that may be instantiated over in this type.
        ///
        /// For instance, Given MyType&lt;object, int[]&gt;,
        ///  an array of types to replace such as {int,object}, and
        ///  an array of replacement types such as {string,__Canon}.
        ///  The result shall be MyType&lt;__Canon, string[]&gt;
        ///
        /// This function cannot be used to replace MyType in the above example.
        /// </summary>
        public static TypeDesc ReplaceTypesInConstructionOfType(this TypeDesc type, TypeDesc[] typesToReplace, TypeDesc[] replacementTypes)
        {
            int directReplacementIndex = Array.IndexOf(typesToReplace, type);

            if (directReplacementIndex != -1)
            {
                return(replacementTypes[directReplacementIndex]);
            }

            if (type.HasInstantiation)
            {
                TypeDesc[] newInstantiation = null;
                Debug.Assert(type is InstantiatedType);
                int instantiationIndex = 0;
                for (; instantiationIndex < type.Instantiation.Length; instantiationIndex++)
                {
                    TypeDesc oldType = type.Instantiation[instantiationIndex];
                    TypeDesc newType = oldType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
                    if ((oldType != newType) || (newInstantiation != null))
                    {
                        if (newInstantiation == null)
                        {
                            newInstantiation = new TypeDesc[type.Instantiation.Length];
                            for (int i = 0; i < instantiationIndex; i++)
                            {
                                newInstantiation[i] = type.Instantiation[i];
                            }
                        }
                        newInstantiation[instantiationIndex] = newType;
                    }
                }
                if (newInstantiation != null)
                {
                    return(type.Context.GetInstantiatedType((MetadataType)type.GetTypeDefinition(), new Instantiation(newInstantiation)));
                }
            }
            else if (type.IsParameterizedType)
            {
                ParameterizedType parameterizedType = (ParameterizedType)type;
                TypeDesc          oldParameter      = parameterizedType.ParameterType;
                TypeDesc          newParameter      = oldParameter.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
                if (oldParameter != newParameter)
                {
                    if (type.IsArray)
                    {
                        ArrayType arrayType = (ArrayType)type;
                        if (arrayType.IsSzArray)
                        {
                            return(type.Context.GetArrayType(newParameter));
                        }
                        else
                        {
                            return(type.Context.GetArrayType(newParameter, arrayType.Rank));
                        }
                    }
                    else if (type.IsPointer)
                    {
                        return(type.Context.GetPointerType(newParameter));
                    }
                    else if (type.IsByRef)
                    {
                        return(type.Context.GetByRefType(newParameter));
                    }
                    Debug.Fail("Unknown form of type");
                }
            }
            else if (type.IsFunctionPointer)
            {
                MethodSignature        oldSig     = ((FunctionPointerType)type).Signature;
                MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(oldSig);
                sigBuilder.ReturnType = oldSig.ReturnType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
                for (int paramIndex = 0; paramIndex < oldSig.Length; paramIndex++)
                {
                    sigBuilder[paramIndex] = oldSig[paramIndex].ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
                }

                MethodSignature newSig = sigBuilder.ToSignature();
                if (newSig != oldSig)
                {
                    return(type.Context.GetFunctionPointerType(newSig));
                }
            }

            return(type);
        }
Пример #30
0
 public bool Equals(MethodSignature otherSignature)
 {
     return(Equals(otherSignature, allowCovariantReturn: false));
 }
Пример #31
0
 static public MethodDesc GetDefaultConstructor(this TypeDesc type)
 {
     // TODO: Do we want check for specialname/rtspecialname? Maybe add another overload on GetMethod?
     var sig = new MethodSignature(0, 0, type.Context.GetWellKnownType(WellKnownType.Void), Array.Empty<TypeDesc>());
     return type.GetMethod(".ctor", sig);
 }
Пример #32
0
        public ILImporter(Compilation compilation, CppWriter writer, MethodDesc method, MethodIL methodIL)
        {
            _compilation = compilation;
            _nodeFactory = _compilation.NodeFactory;

            _writer = writer;

            _method = method;
            _methodSignature = method.Signature;

            _typeSystemContext = method.Context;

            if (!_methodSignature.IsStatic)
                _thisType = method.OwningType;

            _methodIL = methodIL;

            _ilBytes = _methodIL.GetILBytes();
            _locals = _methodIL.GetLocals();

            var ilExceptionRegions = _methodIL.GetExceptionRegions();
            _exceptionRegions = new ExceptionRegion[ilExceptionRegions.Length];
            for (int i = 0; i < ilExceptionRegions.Length; i++)
            {
                _exceptionRegions[i] = new ExceptionRegion() { ILRegion = ilExceptionRegions[i] };
            }
        }
Пример #33
0
        public MethodSignature ToSignature()
        {
            if (_template == null ||
                _flags != _template._flags ||
                _genericParameterCount != _template._genericParameterCount ||
                _returnType != _template._returnType ||
                _parameters != _template._parameters)
            {
                _template = new MethodSignature(_flags, _genericParameterCount, _returnType, _parameters);
            }

            return _template;
        }
Пример #34
0
        public void AppendCppMethodDeclaration(CppGenerationBuffer sb, MethodDesc method, bool implementation, string externalMethodName = null, MethodSignature methodSignature = null)
        {
            if (methodSignature == null)
                methodSignature = method.Signature;

            if (externalMethodName != null)
            {
                sb.Append("extern \"C\" ");
            }
            else
            {
                if (!implementation)
                {
                    sb.Append("static ");
                }
            }
            sb.Append(GetCppSignatureTypeName(methodSignature.ReturnType));
            sb.Append(" ");
            if (externalMethodName != null)
            {
                sb.Append(externalMethodName);
            }
            else
            {
                if (implementation)
                {
                    sb.Append(GetCppMethodDeclarationName(method.OwningType, GetCppMethodName(method)));
                }
                else
                {
                    sb.Append(GetCppMethodName(method));
                }
            }
            sb.Append("(");
            bool hasThis = !methodSignature.IsStatic;
            int argCount = methodSignature.Length;
            if (hasThis)
                argCount++;

            List<string> parameterNames = null;
            if (method != null)
            {
                IEnumerable<string> parameters = GetParameterNamesForMethod(method);
                if (parameters != null)
                {
                    parameterNames = new List<string>(parameters);
                    if (parameterNames.Count != 0)
                    {
                        System.Diagnostics.Debug.Assert(parameterNames.Count == argCount);
                    }
                    else
                    {
                        parameterNames = null;
                    }
                }
            }

            for (int i = 0; i < argCount; i++)
            {
                if (hasThis)
                {
                    if (i == 0)
                    {
                        var thisType = method.OwningType;
                        if (thisType.IsValueType)
                            thisType = thisType.MakeByRefType();
                        sb.Append(GetCppSignatureTypeName(thisType));
                    }
                    else
                    {
                        sb.Append(GetCppSignatureTypeName(methodSignature[i - 1]));
                    }
                }
                else
                {
                    sb.Append(GetCppSignatureTypeName(methodSignature[i]));
                }
                if (implementation)
                {
                    sb.Append(" ");

                    if (parameterNames != null)
                    {
                        sb.Append(SanitizeCppVarName(parameterNames[i]));
                    }
                    else
                    {
                        sb.Append("_a");
                        sb.Append(i.ToStringInvariant());
                    }
                }
                if (i != argCount - 1)
                    sb.Append(", ");
            }
            sb.Append(")");
            if (!implementation)
                sb.Append(";");
        }
Пример #35
0
 public ILToken NewToken(MethodSignature value)
 {
     return NewToken(value, 0x11000000);
 }
Пример #36
0
 public SignatureEnumerator(MethodSignature signature)
 {
     _signature = signature;
     _index     = -1;
 }
Пример #37
0
 private void PassCallArguments(MethodSignature methodSignature, TypeDesc thisArgument)
 {
     int signatureLength = methodSignature.Length;
     int argumentsCount = (thisArgument != null) ? (signatureLength + 1) : signatureLength;
     int startingIndex = _stack.Top - argumentsCount;
     for (int i = 0; i < argumentsCount; i++)
     {
         var op = _stack[startingIndex + i];
         int argIndex = signatureLength - (argumentsCount - i);
         TypeDesc argType;
         if (argIndex == -1)
         {
             argType = thisArgument;
         }
         else
         {
             argType = methodSignature[argIndex];
         }
         AppendCastIfNecessary(argType, op);
         Append(op);
         if (i + 1 != argumentsCount)
             Append(", ");
     }
     _stack.PopN(argumentsCount);
 }
Пример #38
0
        private void AppendSignaturePrefix(StringBuilder sb, MethodSignature signature)
        {
            if (!signature.IsStatic)
                sb.Append("instance ");

            this.TypeNameFormatter.AppendNameWithValueClassPrefix(sb, signature.ReturnType);
        }
Пример #39
0
        internal void AppendSignatureTypeDef(CppGenerationBuffer sb, string name, MethodSignature methodSignature, TypeDesc thisArgument)
        {
            sb.AppendLine();
            sb.Append("typedef ");
            sb.Append(GetCppSignatureTypeName(methodSignature.ReturnType));
            sb.Append("(*");
            sb.Append(name);
            sb.Append(")(");

            int argCount = methodSignature.Length;
            if (thisArgument != null)
                argCount++;
            for (int i = 0; i < argCount; i++)
            {
                if (thisArgument != null)
                {
                    if (i == 0)
                    {
                        sb.Append(GetCppSignatureTypeName(thisArgument));
                    }
                    else
                    {
                        sb.Append(GetCppSignatureTypeName(methodSignature[i - 1]));
                    }
                }
                else
                {
                    sb.Append(GetCppSignatureTypeName(methodSignature[i]));
                }
                if (i != argCount - 1)
                    sb.Append(", ");
            }
            sb.Append(");");
        }
Пример #40
0
        private void AppendSignatureArgumentList(StringBuilder sb, MethodSignature signature)
        {
            for (int i = 0; i < signature.Length; i++)
            {
                if (i != 0)
                    sb.Append(", ");

                this.TypeNameFormatter.AppendNameWithValueClassPrefix(sb, signature[i]);
            }
        }
Пример #41
0
        private void Get_CORINFO_SIG_INFO(MethodSignature signature, out CORINFO_SIG_INFO sig)
        {
            sig.callConv = (CorInfoCallConv)0;
            if (!signature.IsStatic) sig.callConv |= CorInfoCallConv.CORINFO_CALLCONV_HASTHIS;

            TypeDesc returnType = signature.ReturnType;

            CorInfoType corInfoRetType = asCorInfoType(signature.ReturnType, out sig.retTypeClass);
            sig._retType = (byte)corInfoRetType;
            sig.retTypeSigClass = sig.retTypeClass; // The difference between the two is not relevant for ILCompiler

            sig.flags = 0;    // used by IL stubs code

            sig.numArgs = (ushort)signature.Length;

            sig.args = (CORINFO_ARG_LIST_STRUCT_*)0; // CORINFO_ARG_LIST_STRUCT_ is argument index

            // TODO: Shared generic
            sig.sigInst.classInst = null;
            sig.sigInst.classInstCount = 0;
            sig.sigInst.methInst = null;
            sig.sigInst.methInstCount = 0;

            sig.pSig = (byte*)ObjectToHandle(signature);
            sig.cbSig = 0; // Not used by the JIT
            sig.scope = null; // Not used by the JIT
            sig.token = 0; // Not used by the JIT

            // TODO: Shared generic
            // if (ftn->RequiresInstArg())
            // {
            //     sig.callConv = (CorInfoCallConv)(sig.callConv | CORINFO_CALLCONV_PARAMTYPE);
            // }
        }
Пример #42
0
        private void Get_CORINFO_SIG_INFO(MethodSignature signature, out CORINFO_SIG_INFO sig)
        {
            sig.callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask);
            if (!signature.IsStatic) sig.callConv |= CorInfoCallConv.CORINFO_CALLCONV_HASTHIS;

            TypeDesc returnType = signature.ReturnType;

            CorInfoType corInfoRetType = asCorInfoType(signature.ReturnType, out sig.retTypeClass);
            sig._retType = (byte)corInfoRetType;
            sig.retTypeSigClass = sig.retTypeClass; // The difference between the two is not relevant for ILCompiler

            sig.flags = 0;    // used by IL stubs code

            sig.numArgs = (ushort)signature.Length;

            sig.args = (CORINFO_ARG_LIST_STRUCT_*)0; // CORINFO_ARG_LIST_STRUCT_ is argument index

            sig.sigInst.classInst = null; // Not used by the JIT 
            sig.sigInst.classInstCount = 0; // Not used by the JIT 
            sig.sigInst.methInst = null; // Not used by the JIT 
            sig.sigInst.methInstCount = (uint)signature.GenericParameterCount;

            sig.pSig = (byte*)ObjectToHandle(signature);
            sig.cbSig = 0; // Not used by the JIT
            sig.scope = null; // Not used by the JIT
            sig.token = 0; // Not used by the JIT
        }
Пример #43
0
        public override MethodIL EmitIL()
        {
            TypeDesc[] targetMethodParameters = new TypeDesc[Signature.Length + 1];
            targetMethodParameters[0] = Context.GetWellKnownType(WellKnownType.Object);

            for (int i = 0; i < Signature.Length; i++)
            {
                targetMethodParameters[i + 1] = Signature[i];
            }

            var targetMethodSignature = new MethodSignature(
                Signature.Flags | MethodSignatureFlags.Static, 0, Signature.ReturnType, targetMethodParameters);

            var emitter = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            // Load the stored 'this'
            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(HelperObjectField));

            // Load all arguments except 'this'
            for (int i = 0; i < Signature.Length; i++)
            {
                codeStream.EmitLdArg(i + 1);
            }

            // Indirectly call the delegate target static method.
            codeStream.EmitLdArg(0);
            codeStream.Emit(ILOpcode.ldfld, emitter.NewToken(ExtraFunctionPointerOrDataField));
            codeStream.Emit(ILOpcode.calli, emitter.NewToken(targetMethodSignature));
            codeStream.Emit(ILOpcode.ret);

            return emitter.Link(this);
        }
Пример #44
0
 public MissingMethodException(TypeDesc owningType, string methodName, MethodSignature signature)
     : this(ExceptionStringID.MissingField, Format.Method(owningType, methodName, signature))
 {
 }
Пример #45
0
        public MethodIL EmitIL()
        {
            MethodSignature targetMethodSignature = _targetMethod.Signature;

            // We have 4 code streams:
            // - _marshallingCodeStream is used to convert each argument into a native type and 
            // store that into the local
            // - callsiteSetupCodeStream is used to used to load each previously generated local
            // and call the actual target native method.
            // - _returnValueMarshallingCodeStream is used to convert the native return value 
            // to managed one.
            // - _unmarshallingCodestream is used to propagate [out] native arguments values to 
            // managed ones.
            _emitter = new ILEmitter();
            _marshallingCodeStream = _emitter.NewCodeStream();
            ILCodeStream callsiteSetupCodeStream = _emitter.NewCodeStream();
            _returnValueMarshallingCodeStream = _emitter.NewCodeStream();
            _unmarshallingCodestream = _emitter.NewCodeStream();

            TypeDesc[] nativeParameterTypes = new TypeDesc[targetMethodSignature.Length];

            //
            // Parameter marshalling
            //

            //
            // Convert each argument to something we can pass to native and store it in a local.
            // Then load the local in the second code stream.
            //
            for (int i = 0; i < targetMethodSignature.Length; i++)
            {
                // TODO: throw if there's custom marshalling

                _marshallingCodeStream.EmitLdArg(i);

                TypeDesc nativeType = MarshalArgument(targetMethodSignature[i]);

                nativeParameterTypes[i] = nativeType;

                ILLocalVariable vMarshalledTypeTemp = _emitter.NewLocal(nativeType);
                _marshallingCodeStream.EmitStLoc(vMarshalledTypeTemp);

                callsiteSetupCodeStream.EmitLdLoc(vMarshalledTypeTemp);
            }

            //
            // Return value marshalling
            //

            // TODO: throw if SetLastError is true
            // TODO: throw if there's custom marshalling

            TypeDesc nativeReturnType = MarshalReturnValue(targetMethodSignature.ReturnType);

            MethodSignature nativeSig = new MethodSignature(
                targetMethodSignature.Flags, 0, nativeReturnType, nativeParameterTypes);
            MethodDesc nativeMethod =
                new PInvokeTargetNativeMethod(_targetMethod.OwningType, nativeSig, _importMetadata);

            // Call the native method
            callsiteSetupCodeStream.Emit(ILOpcode.call, _emitter.NewToken(nativeMethod));

            _unmarshallingCodestream.Emit(ILOpcode.ret);

            return _emitter.Link();
        }
Пример #46
0
            public static string Method(TypeDesc owningType, string methodName, MethodSignature signature)
            {
                StringBuilder sb = new StringBuilder();

                if (signature != null)
                {
                    sb.Append(ExceptionTypeNameFormatter.Instance.FormatName(signature.ReturnType));
                    sb.Append(' ');
                }

                sb.Append(ExceptionTypeNameFormatter.Instance.FormatName(owningType));
                sb.Append('.');
                sb.Append(methodName);

                if (signature != null)
                {
                    sb.Append('(');
                    for (int i = 0; i < signature.Length; i++)
                    {
                        if (i > 0)
                        {
                            sb.Append(", ");
                        }

                        sb.Append(ExceptionTypeNameFormatter.Instance.FormatName(signature[i]));
                    }
                    sb.Append(')');
                }

                return sb.ToString();
            }
Пример #47
0
        public PInvokeTargetNativeMethod(TypeDesc owningType, MethodSignature signature, PInvokeMetadata methodMetadata)
        {
            _owningType = owningType;
            _signature = signature;
            _methodMetadata = methodMetadata;

            sequenceNumber = System.Threading.Interlocked.Increment(ref nativeMethodCounter);
        }
 public static void ThrowMissingMethodException(TypeDesc owningType, string methodName, MethodSignature signature)
 {
     CoreLibThrow.ThrowMissingMethodException(ExceptionStringID.MissingMethod, Format.Method(owningType, methodName, signature));
 }