Esempio n. 1
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 signatureBuilder = new MethodSignatureBuilder(constructorMethod.Signature);
            signatureBuilder.Flags = MethodSignatureFlags.Static;
            signatureBuilder.ReturnType = constructorMethod.OwningType;

            return constructorMethod.OwningType.GetKnownMethod("Ctor", signatureBuilder.ToSignature());
        }
        protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind)
        {
            MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(_signature);
            sigBuilder.ReturnType = Context.ConvertToCanon(_signature.ReturnType, kind);
            for (int i = 0; i < _signature.Length; i++)
                sigBuilder[i] = Context.ConvertToCanon(_signature[i], kind);

            MethodSignature canonSignature = sigBuilder.ToSignature();
            if (canonSignature != _signature)
                return Context.GetFunctionPointerType(canonSignature);

            return this;
        }
Esempio n. 3
0
        public override TypeDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
        {
            MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(_signature);
            sigBuilder.ReturnType = _signature.ReturnType.InstantiateSignature(typeInstantiation, methodInstantiation);
            for (int i = 0; i < _signature.Length; i++)
                sigBuilder[i] = _signature[i].InstantiateSignature(typeInstantiation, methodInstantiation);

            MethodSignature instantiatedSignature = sigBuilder.ToSignature();
            if (instantiatedSignature != _signature)
                return Context.GetFunctionPointerType(instantiatedSignature);

            return this;
        }
Esempio n. 4
0
        public override TypeDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
        {
            MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(_signature);

            sigBuilder.ReturnType = _signature.ReturnType.InstantiateSignature(typeInstantiation, methodInstantiation);
            for (int i = 0; i < _signature.Length; i++)
            {
                sigBuilder[i] = _signature[i].InstantiateSignature(typeInstantiation, methodInstantiation);
            }

            MethodSignature instantiatedSignature = sigBuilder.ToSignature();

            if (instantiatedSignature != _signature)
            {
                return(Context.GetFunctionPointerType(instantiatedSignature));
            }

            return(this);
        }
Esempio n. 5
0
        protected override TypeDesc ConvertToCanonFormImpl(CanonicalFormKind kind)
        {
            MethodSignatureBuilder sigBuilder = new MethodSignatureBuilder(_signature);

            sigBuilder.ReturnType = Context.ConvertToCanon(_signature.ReturnType, kind);
            for (int i = 0; i < _signature.Length; i++)
            {
                sigBuilder[i] = Context.ConvertToCanon(_signature[i], kind);
            }

            MethodSignature canonSignature = sigBuilder.ToSignature();

            if (canonSignature != _signature)
            {
                return(Context.GetFunctionPointerType(canonSignature));
            }

            return(this);
        }
Esempio n. 6
0
        public override Object GetObject(int token)
        {
            Object o = _methodIL.GetObject(token);

            if (o is MethodDesc)
            {
                o = ((MethodDesc)o).InstantiateSignature(_typeInstantiation, _methodInstantiation);
            }
            else if (o is TypeDesc)
            {
                o = ((TypeDesc)o).InstantiateSignature(_typeInstantiation, _methodInstantiation);
            }
            else if (o is FieldDesc)
            {
                o = ((FieldDesc)o).InstantiateSignature(_typeInstantiation, _methodInstantiation);
            }
            else if (o is MethodSignature)
            {
                MethodSignature template = (MethodSignature)o;
                MethodSignatureBuilder builder = new MethodSignatureBuilder(template);

                builder.ReturnType = template.ReturnType.InstantiateSignature(_typeInstantiation, _methodInstantiation);
                for (int i = 0; i < template.Length; i++)
                    builder[i] = template[i].InstantiateSignature(_typeInstantiation, _methodInstantiation);

                o = builder.ToSignature();
            }


            return o;
        }
Esempio n. 7
0
        public override MethodIL EmitIL()
        {
            // Target has the same signature as the Invoke method, except it's static.
            MethodSignatureBuilder builder = new MethodSignatureBuilder(Signature);
            builder.Flags = Signature.Flags | MethodSignatureFlags.Static;

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

            // 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(builder.ToSignature()));
            codeStream.Emit(ILOpcode.ret);

            return emitter.Link(this);
        }
Esempio n. 8
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);
        }
        /// <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;
        }