Ejemplo n.º 1
0
        private bool IsBlocked(Cts.TypeDesc type)
        {
            if (type.IsArray || type.IsByRef || type.IsPointer)
            {
                return(IsBlocked(((Cts.ParameterizedType)type).ParameterType));
            }

            if (type.IsSignatureVariable)
            {
                return(false);
            }

            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));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns true if this is a type that doesn't require marshalling.
        /// </summary>
        private static bool IsBlittableType(TypeDesc type)
        {
            type = type.UnderlyingType;

            if (type.IsValueType)
            {
                if (type.IsPrimitive)
                {
                    // All primitive types except char and bool are blittable
                    TypeFlags category = type.Category;
                    if (category == TypeFlags.Boolean || category == TypeFlags.Char)
                        return false;

                    return true;
                }

                foreach (FieldDesc field in type.GetFields())
                {
                    if (field.IsStatic)
                        continue;

                    TypeDesc fieldType = field.FieldType;

                    // TODO: we should also reject fields that specify custom marshalling
                    if (!IsBlittableType(fieldType))
                        return false;
                }
                return true;
            }

            if (type.IsPointer)
                return true;

            return false;
        }
Ejemplo n.º 3
0
        private bool IsBlockedCustomAttributeConstantValue(Cts.TypeDesc type, object value)
        {
            if (type.IsSzArray)
            {
                var arrayType  = (Cts.ArrayType)type;
                var arrayValue = (ImmutableArray <Ecma.Decoding.CustomAttributeTypedArgument <Cts.TypeDesc> >)value;

                if (arrayType.ElementType.UnderlyingType.IsPrimitive || arrayType.ElementType.IsString)
                {
                    return(false);
                }

                foreach (var arrayElement in arrayValue)
                {
                    if (IsBlockedCustomAttributeConstantValue(arrayElement.Type, arrayElement.Value))
                    {
                        return(true);
                    }
                    if (arrayElement.Type.IsEnum && IsBlocked(arrayElement.Type))
                    {
                        return(true);
                    }
                }
            }
            else if (value is Cts.TypeDesc)
            {
                Debug.Assert(type is Cts.MetadataType &&
                             ((Cts.MetadataType)type).Name == "Type" &&
                             ((Cts.MetadataType)type).Namespace == "System");
                return(IsBlocked((Cts.TypeDesc)value));
            }

            return(false);
        }
Ejemplo n.º 4
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();
        }
Ejemplo n.º 5
0
        public ExternEETypeSymbolNode(NodeFactory factory, TypeDesc type)
            : base("__EEType_" + NodeFactory.NameMangler.GetMangledTypeName(type))
        {
            _type = type;

            EETypeNode.CheckCanGenerateEEType(factory, type);
        }
        /// <summary>
        /// Returns true if <paramref name="type"/> doesn't require marshalling and can be directly passed
        /// to native code.
        /// </summary>
        private static bool IsSimpleType(TypeDesc type)
        {
            type = type.UnderlyingType;

            switch (type.Category)
            {
                case TypeFlags.Byte:
                case TypeFlags.SByte:
                case TypeFlags.UInt16:
                case TypeFlags.Int16:
                case TypeFlags.UInt32:
                case TypeFlags.Int32:
                case TypeFlags.UInt64:
                case TypeFlags.Int64:
                case TypeFlags.Double:
                case TypeFlags.Single:
                case TypeFlags.UIntPtr:
                case TypeFlags.IntPtr:
                    return true;
            }

            if (type.IsPointer)
                return true;

            return false;
        }
Ejemplo n.º 7
0
 public void AppendName(StringBuilder sb, TypeDesc type)
 {
     switch (type.Category)
     {
         case TypeFlags.Array:
         case TypeFlags.SzArray:
             AppendName(sb, (ArrayType)type);
             return;
         case TypeFlags.ByRef:
             AppendName(sb, (ByRefType)type);
             return;
         case TypeFlags.Pointer:
             AppendName(sb, (PointerType)type);
             return;
         case TypeFlags.GenericParameter:
             AppendName(sb, (GenericParameterDesc)type);
             return;
         case TypeFlags.SignatureTypeVariable:
             AppendName(sb, (SignatureTypeVariable)type);
             return;
         case TypeFlags.SignatureMethodVariable:
             AppendName(sb, (SignatureMethodVariable)type);
             return;
         default:
             Debug.Assert(type.IsDefType);
             AppendName(sb, (DefType)type);
             return;
     }
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Constructs a new instance of <see cref="DelegateCreationInfo"/> set up to construct a delegate of type
        /// '<paramref name="delegateType"/>' pointing to '<paramref name="targetMethod"/>'.
        /// </summary>
        public static DelegateCreationInfo Create(TypeDesc delegateType, MethodDesc targetMethod, NodeFactory factory)
        {
            var context = (CompilerTypeSystemContext)delegateType.Context;
            var systemDelegate = targetMethod.Context.GetWellKnownType(WellKnownType.MulticastDelegate).BaseType;

            int paramCountTargetMethod = targetMethod.Signature.Length;
            if (!targetMethod.Signature.IsStatic)
            {
                paramCountTargetMethod++;
            }

            DelegateInfo delegateInfo = context.GetDelegateInfo(delegateType.GetTypeDefinition());
            int paramCountDelegateClosed = delegateInfo.Signature.Length + 1;
            bool closed = false;
            if (paramCountDelegateClosed == paramCountTargetMethod)
            {
                closed = true;
            }
            else
            {
                Debug.Assert(paramCountDelegateClosed == paramCountTargetMethod + 1);
            }

            if (targetMethod.Signature.IsStatic)
            {
                MethodDesc invokeThunk;
                if (!closed)
                {
                    // Open delegate to a static method
                    invokeThunk = delegateInfo.Thunks[DelegateThunkKind.OpenStaticThunk];
                }
                else
                {
                    // Closed delegate to a static method (i.e. delegate to an extension method that locks the first parameter)
                    invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ClosedStaticThunk];
                }

                var instantiatedDelegateType = delegateType as InstantiatedType;
                if (instantiatedDelegateType != null)
                    invokeThunk = context.GetMethodForInstantiatedType(invokeThunk, instantiatedDelegateType);

                // We use InitializeClosedStaticThunk for both because RyuJIT generates same code for both,
                // but passes null as the first parameter for the open one.
                return new DelegateCreationInfo(
                    factory.MethodEntrypoint(systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null)),
                    factory.MethodEntrypoint(targetMethod),
                    factory.MethodEntrypoint(invokeThunk));
            }
            else
            {
                if (!closed)
                    throw new NotImplementedException("Open instance delegates");

                bool useUnboxingStub = targetMethod.OwningType.IsValueType;

                return new DelegateCreationInfo(
                    factory.MethodEntrypoint(systemDelegate.GetKnownMethod("InitializeClosedInstance", null)),
                    factory.MethodEntrypoint(targetMethod, useUnboxingStub));
            }
        }
Ejemplo n.º 9
0
 public FixupCellMetadataResolver(NativeFormatMetadataUnit metadataUnit, TypeDesc typeContext)
 {
     _metadataUnit = metadataUnit;
     _typeContext = typeContext;
     _methodContext = null;
     _loadContextFromNativeLayout = null;
 }
        /// <summary>
        /// Determine if the construction of a type contains one of a given set of types. This is a deep
        /// scan. For instance, given type MyType&lt;SomeGeneric&lt;int[]&gt;&gt;, and a set of typesToFind
        /// that includes int, this function will return true. Does not detect the open generics that may be
        /// instantiated over in this type. IsConstructedOverType would return false if only passed MyType, 
        /// or SomeGeneric for the above examplt.
        /// </summary>
        /// <param name="type">type to examine</param>
        /// <param name="typesToFind">types to search for in the construction of type</param>
        /// <returns>true if a type in typesToFind is found</returns>
        public static bool IsConstructedOverType(this TypeDesc type, TypeDesc[] typesToFind)
        {
            int directDiscoveryIndex = Array.IndexOf(typesToFind, type);

            if (directDiscoveryIndex != -1)
                return true;

            if (type.HasInstantiation)
            {
                for (int instantiationIndex = 0; instantiationIndex < type.Instantiation.Length; instantiationIndex++)
                {
                    if (type.Instantiation[instantiationIndex].IsConstructedOverType(typesToFind))
                    {
                        return true;
                    }
                }
            }
            else if (type.IsParameterizedType)
            {
                ParameterizedType parameterizedType = (ParameterizedType)type;
                return parameterizedType.ParameterType.IsConstructedOverType(typesToFind);
            }

            return false;
        }
Ejemplo n.º 11
0
        public DelegateInfo(TypeDesc delegateType)
        {
            Debug.Assert(delegateType.IsDelegate);
            Debug.Assert(delegateType.IsTypeDefinition);

            _delegateType = delegateType;
        }
        /// <summary>
        /// Returns a new instantiation that canonicalizes all types in <paramref name="instantiation"/>
        /// if possible under the policy of '<paramref name="kind"/>'
        /// </summary>
        /// <param name="changed">True if the returned instantiation is different from '<paramref name="instantiation"/>'.</param>
        public static Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed)
        {
            TypeDesc[] newInstantiation = null;

            for (int i = 0; i < instantiation.Length; i++)
            {
                TypeDesc typeToConvert = instantiation[i];
                TypeDesc convertedType = ConvertToCanon(typeToConvert, kind);

                if (typeToConvert != convertedType || newInstantiation != null)
                {
                    if (newInstantiation == null)
                    {
                        newInstantiation = new TypeDesc[instantiation.Length];
                        for (int j = 0; j < i; j++)
                            newInstantiation[j] = instantiation[j];
                    }

                    newInstantiation[i] = convertedType;
                }
            }

            changed = newInstantiation != null;
            if (changed)
            {
                return new Instantiation(newInstantiation);
            }

            return instantiation;
        }
Ejemplo n.º 13
0
 // Helper method for nullable transform. Ideally, we would do the nullable transform upfront before
 // the types is build. Unfortunately, there does not seem to be easy way to test for Nullable<> type definition
 // without introducing type builder recursion
 private static RuntimeTypeHandle GetRuntimeTypeHandleWithNullableTransform(TypeBuilder builder, TypeDesc type)
 {
     RuntimeTypeHandle th = builder.GetRuntimeTypeHandle(type);
     if (RuntimeAugments.IsNullable(th))
         th = builder.GetRuntimeTypeHandle(((DefType)type).Instantiation[0]);
     return th;
 }
Ejemplo n.º 14
0
        private static int GetNumberOfBaseSlots(NodeFactory factory, TypeDesc owningType)
        {
            int baseSlots = 0;
            TypeDesc baseType = owningType.BaseType;

            while (baseType != null)
            {
                // Normalize the base type. Necessary to make this work with the lazy vtable slot
                // concept - if we start with a canonical type, the base type could end up being
                // something like Base<__Canon, string>. We would get "0 slots used" for weird
                // base types like this.
                baseType = baseType.ConvertToCanonForm(CanonicalFormKind.Specific);

                // For types that have a generic dictionary, the introduced virtual method slots are
                // prefixed with a pointer to the generic dictionary.
                if (baseType.HasGenericDictionarySlot())
                    baseSlots++;

                IReadOnlyList<MethodDesc> baseVirtualSlots = factory.VTable(baseType).Slots;
                baseSlots += baseVirtualSlots.Count;

                baseType = baseType.BaseType;
            }

            return baseSlots;
        }
Ejemplo n.º 15
0
        private void RootMethods(TypeDesc type, string reason, IRootingServiceProvider rootProvider)
        {
            foreach (MethodDesc method in type.GetMethods())
            {
                // Skip methods with no IL and uninstantiated generic methods
                if (method.IsIntrinsic || method.IsAbstract || method.HasInstantiation)
                    continue;

                if (method.IsInternalCall)
                    continue;

                try
                {
                    CheckCanGenerateMethod(method);
                    rootProvider.AddCompilationRoot(method, reason);
                }
                catch (TypeSystemException)
                {
                    // TODO: fail compilation if a switch was passed

                    // Individual methods can fail to load types referenced in their signatures.
                    // Skip them in library mode since they're not going to be callable.
                    continue;

                    // TODO: Log as a warning
                }
            }
        }
Ejemplo n.º 16
0
 public EETypeNode(TypeDesc type)
 {
     Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific));
     Debug.Assert(!type.IsRuntimeDeterminedSubtype);
     _type = type;
     _optionalFieldsNode = new EETypeOptionalFieldsNode(this);
 }
        public static Instantiation ConvertInstantiationToSharedRuntimeForm(Instantiation instantiation, Instantiation openInstantiation, out bool changed)
        {
            Debug.Assert(instantiation.Length == openInstantiation.Length);

            TypeDesc[] sharedInstantiation = null;

            CanonicalFormKind currentPolicy = CanonicalFormKind.Specific;
            CanonicalFormKind startLoopPolicy;

            do
            {
                startLoopPolicy = currentPolicy;

                for (int instantiationIndex = 0; instantiationIndex < instantiation.Length; instantiationIndex++)
                {
                    TypeDesc typeToConvert = instantiation[instantiationIndex];
                    TypeSystemContext context = typeToConvert.Context;
                    TypeDesc canonForm = context.ConvertToCanon(typeToConvert, ref currentPolicy);
                    TypeDesc runtimeDeterminedForm = typeToConvert;

                    Debug.Assert(openInstantiation[instantiationIndex] is GenericParameterDesc);

                    if ((typeToConvert != canonForm) || typeToConvert.IsCanonicalType)
                    {
                        Debug.Assert(canonForm is DefType);
                        if (sharedInstantiation == null)
                        {
                            sharedInstantiation = new TypeDesc[instantiation.Length];
                            for (int i = 0; i < instantiationIndex; i++)
                                sharedInstantiation[i] = instantiation[i];
                        }

                        runtimeDeterminedForm = context.GetRuntimeDeterminedType(
                            (DefType)canonForm, (GenericParameterDesc)openInstantiation[instantiationIndex]);
                    }

                    if (sharedInstantiation != null)
                    {
                        sharedInstantiation[instantiationIndex] = runtimeDeterminedForm;
                    }
                }

                // Optimization: even if canonical policy changed, we don't actually need to re-run the loop
                // for instantiations that only have a single element.
                if (instantiation.Length == 1)
                {
                    break;
                }

            } while (currentPolicy != startLoopPolicy);

            changed = sharedInstantiation != null;
            if (changed)
            {
                return new Instantiation(sharedInstantiation);
            }

            return instantiation;
        }
        public override DefType[] ComputeRuntimeInterfaces(TypeDesc _type)
        {
            ArrayType arrayType = (ArrayType)_type;
            Debug.Assert(arrayType.IsSzArray);
            TypeDesc arrayOfTInstantiation = _arrayOfTType.MakeInstantiatedType(arrayType.ElementType);

            return arrayOfTInstantiation.RuntimeInterfaces;
        }
Ejemplo n.º 19
0
        public string GetMangledTypeName(TypeDesc type)
        {
            string mangledName;
            if (_mangledTypeNames.TryGetValue(type, out mangledName))
                return mangledName;

            return ComputeMangledTypeName(type);
        }
 public override IEnumerable<MethodDesc> ComputeAllVirtualMethods(TypeDesc type)
 {
     foreach (var method in type.GetMethods())
     {
         if (method.IsVirtual)
             yield return method;
     }
 }
Ejemplo n.º 21
0
 private void AppendOwningType(StringBuilder sb, TypeDesc type)
 {
     // Special case primitive types: we don't want to use short names here
     if (type.IsPrimitive || type.IsString || type.IsObject)
         _typeNameFormatter.AppendNameForNamespaceTypeWithoutAliases(sb, (MetadataType)type);
     else
         AppendType(sb, type, false);
 }
Ejemplo n.º 22
0
        public ArrayMethodILEmitter(ArrayMethod method)
        {
            _method = method;

            ArrayType arrayType = (ArrayType)method.OwningType;
            _rank = arrayType.Rank;
            _elementType = arrayType.ElementType;
        }
Ejemplo n.º 23
0
 protected sealed internal override bool ComputeHasStaticConstructor(TypeDesc type)
 {
     if (type is MetadataType)
     {
         return ((MetadataType)type).GetStaticConstructor() != null;
     }
     return false;
 }
        public override DefType[] ComputeRuntimeInterfaces(TypeDesc _type)
        {
            ArrayType arrayType = (ArrayType)_type;
            Debug.Assert(arrayType.IsSzArray);
            Instantiation arrayInstantiation = new Instantiation(new TypeDesc[] { arrayType.ElementType });
            TypeDesc arrayOfTInstantiation = _arrayOfTType.Context.GetInstantiatedType(_arrayOfTType, arrayInstantiation);

            return arrayOfTInstantiation.RuntimeInterfaces;
        }
Ejemplo n.º 25
0
        public MethodSignature(MethodSignatureFlags flags, int genericParameterCount, TypeDesc returnType, TypeDesc[] parameters)
        {
            _flags = flags;
            _genericParameterCount = genericParameterCount;
            _returnType = returnType;
            _parameters = parameters;

            Debug.Assert(parameters != null, "Parameters must not be null");
        }
Ejemplo n.º 26
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));
            }
        }
 private static TypeDesc ConvertToCanon(TypeDesc typeToConvert, ref CanonicalFormKind kind)
 {
     TypeSystemContext context = typeToConvert.Context;
     if (kind == CanonicalFormKind.Universal)
     {
         return context.UniversalCanonType;
     }
     else if (kind == CanonicalFormKind.Specific)
     {
         if (typeToConvert == context.UniversalCanonType)
         {
             kind = CanonicalFormKind.Universal;
             return context.UniversalCanonType;
         }
         else if (typeToConvert.IsSignatureVariable)
         {
             return typeToConvert;
         }
         else if (typeToConvert.IsDefType)
         {
             if (!typeToConvert.IsValueType)
                 return context.CanonType;
             else if (typeToConvert.HasInstantiation)
             {
                 TypeDesc convertedType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific);
                 if (convertedType.IsCanonicalSubtype(CanonicalFormKind.Universal))
                 {
                     kind = CanonicalFormKind.Universal;
                     return context.UniversalCanonType;
                 }
                 return convertedType;
             }
             else
                 return typeToConvert;
         }
         else if (typeToConvert.IsArray)
         {
             return context.CanonType;
         }
         else
         {
             TypeDesc convertedType = typeToConvert.ConvertToCanonForm(CanonicalFormKind.Specific);
             if (convertedType.IsCanonicalSubtype(CanonicalFormKind.Universal))
             {
                 kind = CanonicalFormKind.Universal;
                 return context.UniversalCanonType;
             }
             return convertedType;
         }
     }
     else
     {
         Debug.Assert(false);
         return null;
     }
 }
Ejemplo n.º 28
0
        public override MetadataRecord HandleType(Cts.TypeDesc type)
        {
            MetadataRecord rec;

            if (type.IsSzArray)
            {
                var arrayType = (Cts.ArrayType)type;
                rec = _types.GetOrCreate(arrayType, _initSzArray ?? (_initSzArray = InitializeSzArray));
            }
            else if (type.IsArray)
            {
                var arrayType = (Cts.ArrayType)type;
                rec = _types.GetOrCreate(arrayType, _initArray ?? (_initArray = InitializeArray));
            }
            else if (type.IsByRef)
            {
                var byRefType = (Cts.ByRefType)type;
                rec = _types.GetOrCreate(byRefType, _initByRef ?? (_initByRef = InitializeByRef));
            }
            else if (type.IsPointer)
            {
                var pointerType = (Cts.PointerType)type;
                rec = _types.GetOrCreate(pointerType, _initPointer ?? (_initPointer = InitializePointer));
            }
            else if (type is Cts.SignatureTypeVariable)
            {
                var variable = (Cts.SignatureTypeVariable)type;
                rec = _types.GetOrCreate(variable, _initTypeVar ?? (_initTypeVar = InitializeTypeVariable));
            }
            else if (type is Cts.SignatureMethodVariable)
            {
                var variable = (Cts.SignatureMethodVariable)type;
                rec = _types.GetOrCreate(variable, _initMethodVar ?? (_initMethodVar = InitializeMethodVariable));
            }
            else if (type is Cts.InstantiatedType)
            {
                var instType = (Cts.InstantiatedType)type;
                rec = _types.GetOrCreate(instType, _initTypeInst ?? (_initTypeInst = InitializeTypeInstance));
            }
            else
            {
                var metadataType = (Cts.MetadataType)type;
                if (_policy.GeneratesMetadata(metadataType))
                {
                    rec = _types.GetOrCreate(metadataType, _initTypeDef ?? (_initTypeDef = InitializeTypeDef));
                }
                else
                {
                    rec = _types.GetOrCreate(metadataType, _initTypeRef ?? (_initTypeRef = InitializeTypeRef));
                }
            }

            Debug.Assert(rec is TypeDefinition || rec is TypeReference || rec is TypeSpecification);

            return(rec);
        }
Ejemplo n.º 29
0
        private TypeDesc GetInstantiationType(ref NativeParser parser, uint arity)
        {
            DefType typeDefinition = (DefType)GetType(ref parser);

            TypeDesc[] typeArguments = new TypeDesc[arity];
            for (uint i = 0; i < arity; i++)
                typeArguments[i] = GetType(ref parser);

            return _typeSystemContext.ResolveGenericInstantiation(typeDefinition, new Instantiation(typeArguments));
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Get the NativeLayout for a type from a ReadyToRun image. 
        /// </summary>
        public bool TryGetMetadataNativeLayout(TypeDesc concreteType, out IntPtr nativeLayoutInfoModule, out uint nativeLayoutInfoToken)
        {
            nativeLayoutInfoModule = default(IntPtr);
            nativeLayoutInfoToken = 0;
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
            var nativeMetadataType = concreteType.GetTypeDefinition() as TypeSystem.NativeFormat.NativeFormatType;
            if (nativeMetadataType == null)
                return false;

            var canonForm = concreteType.ConvertToCanonForm(CanonicalFormKind.Specific);
            var hashCode = canonForm.GetHashCode();

            var loadedModulesCount = RuntimeAugments.GetLoadedModules(null);
            var loadedModuleHandles = new IntPtr[loadedModulesCount];
            var loadedModules = RuntimeAugments.GetLoadedModules(loadedModuleHandles);
            Debug.Assert(loadedModulesCount == loadedModules);

#if SUPPORTS_R2R_LOADING
            foreach (var moduleHandle in loadedModuleHandles)
            {
                ExternalReferencesTable externalFixupsTable;
                NativeHashtable typeTemplatesHashtable = LoadHashtable(moduleHandle, ReflectionMapBlob.MetadataBasedTypeTemplateMap, out externalFixupsTable);

                if (typeTemplatesHashtable.IsNull)
                    continue;

                var enumerator = typeTemplatesHashtable.Lookup(hashCode);
                var nativeMetadataUnit = nativeMetadataType.Context.ResolveMetadataUnit(moduleHandle);

                NativeParser entryParser;
                while (!(entryParser = enumerator.GetNext()).IsNull)
                {
                    var entryTypeHandle = entryParser.GetUnsigned().AsHandle();
                    TypeDesc typeDesc = nativeMetadataUnit.GetType(entryTypeHandle);
                    Debug.Assert(typeDesc != null);
                    if (typeDesc == canonForm)
                    {
                        TypeLoaderLogger.WriteLine("Found metadata template for type " + concreteType.ToString() + ": " + typeDesc.ToString());
                        nativeLayoutInfoToken = (uint)externalFixupsTable.GetRvaFromIndex(entryParser.GetUnsigned());
                        if (nativeLayoutInfoToken == BadTokenFixupValue)
                        {
                            throw new BadImageFormatException();
                        }

                        nativeLayoutInfoModule = moduleHandle;
                        return true;
                    }
                }
            }
#endif
#endif

            return false;
        }
Ejemplo n.º 31
0
 public void AppendType(StringBuilder sb, TypeDesc type, bool forceValueClassPrefix = true)
 {
     // Types referenced from the IL show as instantiated over generic parameter.
     // E.g. "initobj !0" becomes "initobj !T"
     TypeDesc typeInContext = type.InstantiateSignature(
         _methodIL.OwningMethod.OwningType.Instantiation, _methodIL.OwningMethod.Instantiation);
     if (typeInContext.HasInstantiation || forceValueClassPrefix)
         this.TypeNameFormatter.AppendNameWithValueClassPrefix(sb, typeInContext);
     else
         this.TypeNameFormatter.AppendName(sb, typeInContext);
 }
Ejemplo n.º 32
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);
        }
Ejemplo n.º 33
0
        public EETypeNode(NodeFactory factory, TypeDesc type)
        {
            Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific));
            Debug.Assert(!type.IsRuntimeDeterminedSubtype);
            _type = type;
            _optionalFieldsNode = new EETypeOptionalFieldsNode(this);

            // Note: The fact that you can't create invalid EETypeNode is used from many places that grab
            // an EETypeNode from the factory with the sole purpose of making sure the validation has run
            // and that the result of the positive validation is "cached" (by the presence of an EETypeNode).
            CheckCanGenerateEEType(factory, type);
        }
Ejemplo n.º 34
0
        //
        // Is the source type derived from the target type?
        //
        static public bool IsDerived(TypeDesc derivedType, TypeDesc baseType)
        {
            for (;;)
            {
                if (derivedType == baseType)
                    return true;

                derivedType = derivedType.BaseType;
                if (derivedType == null)
                    return false;
            }
        }
Ejemplo n.º 35
0
        private void InitializeTypeInstance(Cts.TypeDesc entity, TypeSpecification record)
        {
            var sig = new TypeInstantiationSignature
            {
                GenericType = HandleType(entity.GetTypeDefinition()),
            };

            for (int i = 0; i < entity.Instantiation.Length; i++)
            {
                sig.GenericTypeArguments.Add(HandleType(entity.Instantiation[i]));
            }

            record.Signature = sig;
        }
Ejemplo n.º 36
0
        private MetadataRecord HandleCustomAttributeConstantValue(Cts.TypeDesc type, object value)
        {
            switch (type.UnderlyingType.Category)
            {
            case Cts.TypeFlags.Boolean:
                return(new ConstantBooleanValue {
                    Value = (bool)value
                });

            case Cts.TypeFlags.Byte:
                return(new ConstantByteValue {
                    Value = (byte)value
                });

            case Cts.TypeFlags.Char:
                return(new ConstantCharValue {
                    Value = (char)value
                });

            case Cts.TypeFlags.Double:
                return(new ConstantDoubleValue {
                    Value = (double)value
                });

            case Cts.TypeFlags.Int16:
                return(new ConstantInt16Value {
                    Value = (short)value
                });

            case Cts.TypeFlags.Int32:
                return(new ConstantInt32Value {
                    Value = (int)value
                });

            case Cts.TypeFlags.Int64:
                return(new ConstantInt64Value {
                    Value = (long)value
                });

            case Cts.TypeFlags.SByte:
                return(new ConstantSByteValue {
                    Value = (sbyte)value
                });

            case Cts.TypeFlags.Single:
                return(new ConstantSingleValue {
                    Value = (float)value
                });

            case Cts.TypeFlags.UInt16:
                return(new ConstantUInt16Value {
                    Value = (ushort)value
                });

            case Cts.TypeFlags.UInt32:
                return(new ConstantUInt32Value {
                    Value = (uint)value
                });

            case Cts.TypeFlags.UInt64:
                return(new ConstantUInt64Value {
                    Value = (ulong)value
                });
            }

            if (type.IsString)
            {
                return(HandleString((string)value));
            }

            if (value == null)
            {
                return(new ConstantReferenceValue());
            }

            if (type.IsSzArray)
            {
                return(HandleCustomAttributeConstantArray(
                           (Cts.ArrayType)type,
                           (ImmutableArray <Ecma.CustomAttributeTypedArgument <Cts.TypeDesc> >)value));
            }

            Debug.Assert(value is Cts.TypeDesc);
            Debug.Assert(type is Cts.MetadataType &&
                         ((Cts.MetadataType)type).Name == "Type" &&
                         ((Cts.MetadataType)type).Namespace == "System");

            return(HandleType((Cts.TypeDesc)value));
        }
Ejemplo n.º 37
0
        public TypeDesc ResolveRuntimeTypeHandle(RuntimeTypeHandle rtth)
        {
            TypeDesc returnedType;

            if (_runtimeTypeHandleResolutionCache.TryGetValue(rtth, out returnedType))
            {
                return(returnedType);
            }

            if (rtth.Equals(CanonType.RuntimeTypeHandle))
            {
                returnedType = CanonType;
            }
            else if (rtth.Equals(UniversalCanonType.RuntimeTypeHandle))
            {
                returnedType = UniversalCanonType;
            }
            else if (RuntimeAugments.IsGenericTypeDefinition(rtth))
            {
                returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth);
                if (returnedType == null)
                {
                    unsafe
                    {
                        TypeDesc[] genericParameters = new TypeDesc[rtth.ToEETypePtr()->GenericArgumentCount];
                        for (int i = 0; i < genericParameters.Length; i++)
                        {
                            genericParameters[i] = GetSignatureVariable(i, false);
                        }

                        returnedType = new NoMetadataType(this, rtth, null, new Instantiation(genericParameters), rtth.GetHashCode());
                    }
                }
            }
            else if (RuntimeAugments.IsGenericType(rtth))
            {
                RuntimeTypeHandle   typeDefRuntimeTypeHandle;
                RuntimeTypeHandle[] genericArgRuntimeTypeHandles;
                typeDefRuntimeTypeHandle = RuntimeAugments.GetGenericInstantiation(rtth, out genericArgRuntimeTypeHandles);

                DefType       typeDef     = (DefType)ResolveRuntimeTypeHandle(typeDefRuntimeTypeHandle);
                Instantiation genericArgs = ResolveRuntimeTypeHandles(genericArgRuntimeTypeHandles);
                returnedType = ResolveGenericInstantiation(typeDef, genericArgs);
            }
            else if (RuntimeAugments.IsArrayType(rtth))
            {
                RuntimeTypeHandle elementTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          elementType       = ResolveRuntimeTypeHandle(elementTypeHandle);
                unsafe
                {
                    if (rtth.ToEETypePtr()->IsSzArray)
                    {
                        returnedType = GetArrayType(elementType);
                    }
                    else
                    {
                        returnedType = GetArrayType(elementType, rtth.ToEETypePtr()->ArrayRank);
                    }
                }
            }
            else if (RuntimeAugments.IsUnmanagedPointerType(rtth))
            {
                RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          targetType       = ResolveRuntimeTypeHandle(targetTypeHandle);
                returnedType = GetPointerType(targetType);
            }
            else if (RuntimeAugments.IsByRefType(rtth))
            {
                RuntimeTypeHandle targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(rtth);
                TypeDesc          targetType       = ResolveRuntimeTypeHandle(targetTypeHandle);
                returnedType = GetByRefType(targetType);
            }
            else
            {
                returnedType = TryGetMetadataBasedTypeFromRuntimeTypeHandle_Uncached(rtth);
                if (returnedType == null)
                {
                    returnedType = new NoMetadataType(this, rtth, null, Instantiation.Empty, rtth.GetHashCode());
                }
            }

            // We either retrieved an existing DefType that is already registered with the runtime
            // or one that is not associated with an MethodTable yet. If it's not associated, associate it.
            if (returnedType.RuntimeTypeHandle.IsNull())
            {
                TypeBuilderState state = returnedType.GetTypeBuilderStateIfExist();
                bool             skipStoringRuntimeTypeHandle = false;

                // If we've already attempted to lookup and failed to retrieve this type handle, we
                // may have already decided to create a new one. In that case, do not attempt to abort
                // that creation process as it may have already begun the process of type creation
                if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle)
                {
                    skipStoringRuntimeTypeHandle = true;
                }

                if (!skipStoringRuntimeTypeHandle)
                {
                    returnedType.SetRuntimeTypeHandleUnsafe(rtth);
                }
            }

            _runtimeTypeHandleResolutionCache.Add(rtth, returnedType);

            return(returnedType.WithDebugName());
        }
            private bool ComputeCanCompareValueTypeBits(MetadataType type)
            {
                Debug.Assert(type.IsValueType);

                if (type.ContainsGCPointers)
                    return false;

                if (type.IsGenericDefinition)
                    return false;

                OverlappingFieldTracker overlappingFieldTracker = new OverlappingFieldTracker(type);

                bool result = true;
                foreach (var field in type.GetFields())
                {
                    if (field.IsStatic)
                        continue;

                    if (!overlappingFieldTracker.TrackField(field))
                    {
                        // This field overlaps with another field - can't compare memory
                        result = false;
                        break;
                    }

                    TypeDesc fieldType = field.FieldType;
                    if (fieldType.IsPrimitive || fieldType.IsEnum || fieldType.IsPointer || fieldType.IsFunctionPointer)
                    {
                        TypeFlags category = fieldType.UnderlyingType.Category;
                        if (category == TypeFlags.Single || category == TypeFlags.Double)
                        {
                            // Double/Single have weird behaviors around negative/positive zero
                            result = false;
                            break;
                        }
                    }
                    else
                    {
                        // Would be a suprise if this wasn't a valuetype. We checked ContainsGCPointers above.
                        Debug.Assert(fieldType.IsValueType);

                        MethodDesc objectEqualsMethod = fieldType.Context._objectEqualsMethod;

                        // If the field overrides Equals, we can't use the fast helper because we need to call the method.
                        if (fieldType.FindVirtualFunctionTargetMethodOnObjectType(objectEqualsMethod).OwningType == fieldType)
                        {
                            result = false;
                            break;
                        }

                        if (!_hashtable.GetOrCreateValue((MetadataType)fieldType).CanCompareValueTypeBits)
                        {
                            result = false;
                            break;
                        }
                    }
                }

                // If there are gaps, we can't memcompare
                if (result && overlappingFieldTracker.HasGaps)
                    result = false;

                return result;
            }
Ejemplo n.º 39
0
        private MetadataRecord HandleCustomAttributeConstantArray(
            Cts.ArrayType type, ImmutableArray <Ecma.CustomAttributeTypedArgument <Cts.TypeDesc> > value)
        {
            Cts.TypeDesc elementType = type.ElementType;

            switch (elementType.UnderlyingType.Category)
            {
            case Cts.TypeFlags.Boolean:
                return(new ConstantBooleanArray {
                    Value = GetCustomAttributeConstantArrayElements <bool>(value)
                });

            case Cts.TypeFlags.Byte:
                return(new ConstantByteArray {
                    Value = GetCustomAttributeConstantArrayElements <byte>(value)
                });

            case Cts.TypeFlags.Char:
                return(new ConstantCharArray {
                    Value = GetCustomAttributeConstantArrayElements <char>(value)
                });

            case Cts.TypeFlags.Double:
                return(new ConstantDoubleArray {
                    Value = GetCustomAttributeConstantArrayElements <double>(value)
                });

            case Cts.TypeFlags.Int16:
                return(new ConstantInt16Array {
                    Value = GetCustomAttributeConstantArrayElements <short>(value)
                });

            case Cts.TypeFlags.Int32:
                return(new ConstantInt32Array {
                    Value = GetCustomAttributeConstantArrayElements <int>(value)
                });

            case Cts.TypeFlags.Int64:
                return(new ConstantInt64Array {
                    Value = GetCustomAttributeConstantArrayElements <long>(value)
                });

            case Cts.TypeFlags.SByte:
                return(new ConstantSByteArray {
                    Value = GetCustomAttributeConstantArrayElements <sbyte>(value)
                });

            case Cts.TypeFlags.Single:
                return(new ConstantSingleArray {
                    Value = GetCustomAttributeConstantArrayElements <float>(value)
                });

            case Cts.TypeFlags.UInt16:
                return(new ConstantUInt16Array {
                    Value = GetCustomAttributeConstantArrayElements <ushort>(value)
                });

            case Cts.TypeFlags.UInt32:
                return(new ConstantUInt32Array {
                    Value = GetCustomAttributeConstantArrayElements <uint>(value)
                });

            case Cts.TypeFlags.UInt64:
                return(new ConstantUInt64Array {
                    Value = GetCustomAttributeConstantArrayElements <ulong>(value)
                });
            }

            if (elementType.IsString)
            {
                var record = new ConstantStringArray();
                record.Value.Capacity = value.Length;
                foreach (var element in value)
                {
                    MetadataRecord elementRecord = element.Value == null ?
                                                   (MetadataRecord) new ConstantReferenceValue() : HandleString((string)element.Value);
                    record.Value.Add(elementRecord);
                }
                return(record);
            }

            var result = new ConstantHandleArray();

            result.Value.Capacity = value.Length;
            for (int i = 0; i < value.Length; i++)
            {
                MetadataRecord elementRecord = HandleCustomAttributeConstantValue(value[i].Type, value[i].Value);
                if (value[i].Type.IsEnum)
                {
                    elementRecord = new ConstantBoxedEnumValue
                    {
                        Value = elementRecord,
                        Type  = HandleType(value[i].Type)
                    };
                }
                result.Value.Add(elementRecord);
            }

            return(result);
        }
 public TypeState(TypeDesc type, TypeStateHashtable hashtable)
 {
     Type = type;
     _hashtable = hashtable;
 }
Ejemplo n.º 41
0
        /// <summary>
        /// Attempts to resolve constrained call to <paramref name="interfaceMethod"/> into a concrete non-unboxing
        /// method on <paramref name="constrainedType"/>.
        /// The ability to resolve constraint methods is affected by the degree of code sharing we are performing
        /// for generic code.
        /// </summary>
        /// <returns>The resolved method or null if the constraint couldn't be resolved.</returns>
        static public MethodDesc TryResolveConstraintMethodApprox(this MetadataType constrainedType, TypeDesc interfaceType, MethodDesc interfaceMethod, out bool forceRuntimeLookup)
        {
            forceRuntimeLookup = false;

            // We can't resolve constraint calls effectively for reference types, and there's
            // not a lot of perf. benefit in doing it anyway.
            if (!constrainedType.IsValueType)
            {
                return(null);
            }

            // Non-virtual methods called through constraints simply resolve to the specified method without constraint resolution.
            if (!interfaceMethod.IsVirtual)
            {
                return(null);
            }

            MetadataType canonMT = constrainedType;

            MethodDesc method;

            MethodDesc genInterfaceMethod = interfaceMethod.GetMethodDefinition();

            if (genInterfaceMethod.OwningType.IsInterface)
            {
                // Sometimes (when compiling shared generic code)
                // we don't have enough exact type information at JIT time
                // even to decide whether we will be able to resolve to an unboxed entry point...
                // To cope with this case we always go via the helper function if there's any
                // chance of this happening by checking for all interfaces which might possibly
                // be compatible with the call (verification will have ensured that
                // at least one of them will be)

                // Enumerate all potential interface instantiations

                // TODO: this code assumes no shared generics
                Debug.Assert(interfaceType == interfaceMethod.OwningType);

                method = VirtualFunctionResolution.ResolveInterfaceMethodToVirtualMethodOnType(genInterfaceMethod, constrainedType);
            }
            else if (genInterfaceMethod.IsVirtual)
            {
                method = VirtualFunctionResolution.FindVirtualFunctionTargetMethodOnObjectType(genInterfaceMethod, constrainedType);
            }
            else
            {
                // The method will be null if calling a non-virtual instance
                // methods on System.Object, i.e. when these are used as a constraint.
                method = null;
            }

            if (method == null)
            {
                // Fall back to VSD
                return(null);
            }

            //#TryResolveConstraintMethodApprox_DoNotReturnParentMethod
            // Only return a method if the value type itself declares the method,
            // otherwise we might get a method from Object or System.ValueType
            if (!method.OwningType.IsValueType)
            {
                // Fall back to VSD
                return(null);
            }

            // We've resolved the method, ignoring its generic method arguments
            // If the method is a generic method then go and get the instantiated descriptor
            if (interfaceMethod.HasInstantiation)
            {
                method = method.InstantiateSignature(interfaceType.Instantiation, interfaceMethod.Instantiation);
            }

            Debug.Assert(method != null);
            //assert(!pMD->IsUnboxingStub());

            return(method);
        }
Ejemplo n.º 42
0
 /// <summary>
 /// Returns true if '<paramref name="thisType"/>' can be cast to '<paramref name="otherType"/>'.
 /// Assumes '<paramref name="thisType"/>' is in it's boxed form if it's a value type (i.e.
 /// [System.Int32].CanCastTo([System.Object]) will return true).
 /// </summary>
 public static bool CanCastTo(this TypeDesc thisType, TypeDesc otherType)
 {
     return(thisType.CanCastToInternal(otherType, null));
 }
Ejemplo n.º 43
0
        private int _rank; // -1 for regular single dimensional arrays, > 0 for multidimensional arrays

        internal ArrayType(TypeDesc elementType, int rank)
            : base(elementType)
        {
            _rank = rank;
        }
        /// <summary>
        /// Replace some of the types in a method's construction with a new set of types.
        /// Does not replace the open generics that may be instantiated over in this type.
        ///
        /// For instance, Given MyType&lt;object, int[]&gt;.Function&lt;short&gt;(),
        ///  an array of types to replace such as {int,short}, and
        ///  an array of replacement types such as {string,char}.
        ///  The result shall be MyType&lt;object, string[]&gt;.Function&lt;char&gt;
        ///
        /// This function cannot be used to replace MyType in the above example.
        /// </summary>
        public static MethodDesc ReplaceTypesInConstructionOfMethod(this MethodDesc method, TypeDesc[] typesToReplace, TypeDesc[] replacementTypes)
        {
            TypeDesc   newOwningType      = method.OwningType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
            MethodDesc methodOnOwningType = null;
            bool       owningTypeChanged  = false;

            if (newOwningType == method.OwningType)
            {
                methodOnOwningType = method.GetMethodDefinition();
            }
            else
            {
                methodOnOwningType = TypeSystemHelpers.FindMethodOnExactTypeWithMatchingTypicalMethod(newOwningType, method);
                owningTypeChanged  = true;
            }

            MethodDesc result;

            if (!method.HasInstantiation)
            {
                result = methodOnOwningType;
            }
            else
            {
                Debug.Assert(method is InstantiatedMethod);

                TypeDesc[] newInstantiation   = null;
                int        instantiationIndex = 0;
                for (; instantiationIndex < method.Instantiation.Length; instantiationIndex++)
                {
                    TypeDesc oldType = method.Instantiation[instantiationIndex];
                    TypeDesc newType = oldType.ReplaceTypesInConstructionOfType(typesToReplace, replacementTypes);
                    if ((oldType != newType) || (newInstantiation != null))
                    {
                        if (newInstantiation == null)
                        {
                            newInstantiation = new TypeDesc[method.Instantiation.Length];
                            for (int i = 0; i < instantiationIndex; i++)
                            {
                                newInstantiation[i] = method.Instantiation[i];
                            }
                        }
                        newInstantiation[instantiationIndex] = newType;
                    }
                }

                if (newInstantiation != null)
                {
                    result = method.Context.GetInstantiatedMethod(methodOnOwningType, new Instantiation(newInstantiation));
                }
                else if (owningTypeChanged)
                {
                    result = method.Context.GetInstantiatedMethod(methodOnOwningType, method.Instantiation);
                }
                else
                {
                    result = method;
                }
            }

            return(result);
        }
Ejemplo n.º 45
0
        public override MetadataRecord HandleType(Cts.TypeDesc type)
        {
            MetadataRecord rec;

            if (_types.TryGet(type, out rec))
            {
                return(rec);
            }

            switch (type.Category)
            {
            case Cts.TypeFlags.SzArray:
                rec = _types.Create((Cts.ArrayType)type, _initSzArray ??= InitializeSzArray);
                break;

            case Cts.TypeFlags.Array:
                rec = _types.Create((Cts.ArrayType)type, _initArray ??= InitializeArray);
                break;

            case Cts.TypeFlags.ByRef:
                rec = _types.Create((Cts.ByRefType)type, _initByRef ??= InitializeByRef);
                break;

            case Cts.TypeFlags.Pointer:
                rec = _types.Create((Cts.PointerType)type, _initPointer ??= InitializePointer);
                break;

            case Cts.TypeFlags.FunctionPointer:
                rec = _types.Create((Cts.FunctionPointerType)type, _initFunctionPointer ??= InitializeFunctionPointer);
                break;

            case Cts.TypeFlags.SignatureTypeVariable:
                rec = _types.Create((Cts.SignatureTypeVariable)type, _initTypeVar ??= InitializeTypeVariable);
                break;

            case Cts.TypeFlags.SignatureMethodVariable:
                rec = _types.Create((Cts.SignatureMethodVariable)type, _initMethodVar ??= InitializeMethodVariable);
                break;

            default:
            {
                Debug.Assert(type.IsDefType);

                if (!type.IsTypeDefinition)
                {
                    // Instantiated generic type
                    rec = _types.Create(type, _initTypeInst ??= InitializeTypeInstance);
                }
                else
                {
                    // Type definition
                    var metadataType = (Cts.MetadataType)type;
                    if (_policy.GeneratesMetadata(metadataType))
                    {
                        Debug.Assert(!_policy.IsBlocked(metadataType));
                        rec = _types.Create(metadataType, _initTypeDef ??= InitializeTypeDef);
                    }
                    else
                    {
                        rec = _types.Create(metadataType, _initTypeRef ??= InitializeTypeRef);
                    }
                }
            }
            break;
            }


            Debug.Assert(rec is TypeDefinition || rec is TypeReference || rec is TypeSpecification);

            return(rec);
        }
Ejemplo n.º 46
0
 internal PointerType(TypeDesc parameterType)
     : base(parameterType)
 {
 }
Ejemplo n.º 47
0
 private void InitializeParameterTypeSignature(Cts.TypeDesc entity, ParameterTypeSignature record)
 {
     // TODO: CustomModifiers
     record.Type = HandleType(entity);
 }
Ejemplo n.º 48
0
 private ParameterTypeSignature HandleParameterTypeSignature(Cts.TypeDesc parameter)
 {
     return(_paramSigs.GetOrCreate(parameter, _initParamSig ?? (_initParamSig = InitializeParameterTypeSignature)));
 }
        /// <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);
        }
Ejemplo n.º 50
0
        private void AddToFieldLayout(int offset, TypeDesc fieldType)
        {
            if (fieldType.IsGCPointer)
            {
                if (offset % _pointerSize != 0)
                {
                    // Misaligned ORef
                    ThrowFieldLayoutError(offset);
                }
                SetFieldLayout(offset, _pointerSize, FieldLayoutTag.ORef);
            }
            else if (fieldType.IsPointer || fieldType.IsFunctionPointer)
            {
                SetFieldLayout(offset, _pointerSize, FieldLayoutTag.NonORef);
            }
            else if (fieldType.IsValueType)
            {
                MetadataType mdType    = (MetadataType)fieldType;
                int          fieldSize = mdType.InstanceByteCountUnaligned.AsInt;
                if (!mdType.ContainsGCPointers && !mdType.IsByRefLike)
                {
                    // Plain value type, mark the entire range as NonORef
                    SetFieldLayout(offset, fieldSize, FieldLayoutTag.NonORef);
                }
                else
                {
                    if (offset % _pointerSize != 0)
                    {
                        // Misaligned struct with GC pointers or ByRef
                        ThrowFieldLayoutError(offset);
                    }

                    List <FieldLayoutInterval> fieldRefMap = new();
                    MarkByRefAndORefLocations(mdType, fieldRefMap, offset: 0);

                    // Merge in fieldRefMap from structure specifying not attributed intervals as NonORef
                    int lastGCRegionReportedEnd = 0;

                    foreach (var gcRegion in fieldRefMap)
                    {
                        SetFieldLayout(offset + lastGCRegionReportedEnd, gcRegion.Start - lastGCRegionReportedEnd, FieldLayoutTag.NonORef);
                        Debug.Assert(gcRegion.Tag == FieldLayoutTag.ORef || gcRegion.Tag == FieldLayoutTag.ByRef);
                        SetFieldLayout(offset + gcRegion.Start, gcRegion.Size, gcRegion.Tag);
                        lastGCRegionReportedEnd = gcRegion.EndSentinel;
                    }

                    if (fieldRefMap.Count > 0)
                    {
                        int trailingRegionStart = fieldRefMap[fieldRefMap.Count - 1].EndSentinel;
                        int trailingRegionSize  = fieldSize - trailingRegionStart;
                        SetFieldLayout(offset + trailingRegionStart, trailingRegionSize, FieldLayoutTag.NonORef);
                    }
                }
            }
            else if (fieldType.IsByRef)
            {
                if (offset % _pointerSize != 0)
                {
                    // Misaligned pointer field
                    ThrowFieldLayoutError(offset);
                }
                SetFieldLayout(offset, _pointerSize, FieldLayoutTag.ByRef);
            }
            else
            {
                Debug.Assert(false, fieldType.ToString());
            }
        }
Ejemplo n.º 51
0
        private static bool CanCastByVarianceToInterfaceOrDelegate(this TypeDesc thisType, TypeDesc otherType, StackOverflowProtect protectInput)
        {
            if (!thisType.HasSameTypeDefinition(otherType))
            {
                return(false);
            }

            var stackOverflowProtectKey = new CastingPair(thisType, otherType);

            if (protectInput != null)
            {
                if (protectInput.Contains(stackOverflowProtectKey))
                {
                    return(false);
                }
            }

            StackOverflowProtect protect = new StackOverflowProtect(stackOverflowProtectKey, protectInput);

            Instantiation instantiationThis   = thisType.Instantiation;
            Instantiation instantiationTarget = otherType.Instantiation;
            Instantiation instantiationOpen   = thisType.GetTypeDefinition().Instantiation;

            Debug.Assert(instantiationThis.Length == instantiationTarget.Length &&
                         instantiationThis.Length == instantiationOpen.Length);

            for (int i = 0; i < instantiationThis.Length; i++)
            {
                TypeDesc arg       = instantiationThis[i];
                TypeDesc targetArg = instantiationTarget[i];

                if (arg != targetArg)
                {
                    GenericParameterDesc openArgType = (GenericParameterDesc)instantiationOpen[i];

                    switch (openArgType.Variance)
                    {
                    case GenericVariance.Covariant:
                        if (!arg.IsBoxedAndCanCastTo(targetArg, protect))
                        {
                            return(false);
                        }
                        break;

                    case GenericVariance.Contravariant:
                        if (!targetArg.IsBoxedAndCanCastTo(arg, protect))
                        {
                            return(false);
                        }
                        break;

                    default:
                        // non-variant
                        Debug.Assert(openArgType.Variance == GenericVariance.None);
                        return(false);
                    }
                }
            }

            return(true);
        }
 /// <summary>
 /// Retrieves an existing <see cref="TypeDefinition"/>, <see cref="TypeReference"/>,
 /// or <see cref="TypeSpecification"/> record representing specified type in the metadata writer object
 /// model, or creates a new one.
 /// </summary>
 public abstract MetadataRecord HandleType(Cts.TypeDesc type);
        /// <summary>
        /// Parses the string '<paramref name="name"/>' and returns the type corresponding to the parsed type name.
        /// The type name string should be in the 'SerString' format as defined by the ECMA-335 standard.
        /// </summary>
        public static TypeDesc GetTypeByCustomAttributeTypeName(this ModuleDesc module, string name)
        {
            TypeDesc loadedType;

            StringBuilder genericTypeDefName = new StringBuilder(name.Length);

            var ch      = name.Begin();
            var nameEnd = name.End();

            for (; ch < nameEnd; ++ch)
            {
                // Always pass escaped characters through.
                if (ch.Current == '\\')
                {
                    genericTypeDefName.Append(ch.Current);
                    ++ch;
                    if (ch < nameEnd)
                    {
                        genericTypeDefName.Append(ch.Current);
                    }
                    continue;
                }

                // The type def name ends if

                // The start of a generic argument list
                if (ch.Current == '[')
                {
                    break;
                }

                // Indication that the type is a pointer
                if (ch.Current == '*')
                {
                    break;
                }

                // Indication that the type is a reference
                if (ch.Current == '&')
                {
                    break;
                }

                // A comma that indicates that the rest of the name is an assembly reference
                if (ch.Current == ',')
                {
                    break;
                }

                genericTypeDefName.Append(ch.Current);
            }

            ModuleDesc   homeModule   = module;
            AssemblyName homeAssembly = FindAssemblyIfNamePresent(name);

            if (homeAssembly != null)
            {
                homeModule = module.Context.ResolveAssembly(homeAssembly);
            }
            MetadataType typeDef = ResolveCustomAttributeTypeNameToTypeDesc(genericTypeDefName.ToString(), homeModule);

            ArrayBuilder <TypeDesc> genericArgs = new ArrayBuilder <TypeDesc>();

            // Followed by generic instantiation parameters (but check for the array case)
            if (ch < nameEnd && ch.Current == '[' && (ch + 1) < nameEnd && (ch + 1).Current != ']' && (ch + 1).Current != ',')
            {
                ch++;                                                                   // truncate the '['
                var genericInstantiationEnd = ch + ReadTypeArgument(ch, nameEnd, true); // find the end of the instantiation list
                while (ch < genericInstantiationEnd)
                {
                    if (ch.Current == ',')
                    {
                        ch++;
                    }

                    int    argLen = ReadTypeArgument(ch, name.End(), false);
                    string typeArgName;
                    if (ch.Current == '[')
                    {
                        // This type argument name is stringified,
                        // we need to remove the [] from around it
                        ch++;
                        typeArgName = StringIterator.Substring(ch, ch + (argLen - 2));
                        ch         += argLen - 1;
                    }
                    else
                    {
                        typeArgName = StringIterator.Substring(ch, ch + argLen);
                        ch         += argLen;
                    }

                    TypeDesc argType = module.GetTypeByCustomAttributeTypeName(typeArgName);
                    genericArgs.Add(argType);
                }

                Debug.Assert(ch == genericInstantiationEnd);
                ch++;

                loadedType = typeDef.MakeInstantiatedType(new Instantiation(genericArgs.ToArray()));
            }
            else
            {
                // Non-generic type
                loadedType = typeDef;
            }

            // At this point the characters following may be any number of * characters to indicate pointer depth
            while (ch < nameEnd)
            {
                if (ch.Current == '*')
                {
                    loadedType = loadedType.MakePointerType();
                }
                else
                {
                    break;
                }
                ch++;
            }

            // Followed by any number of "[]" or "[,*]" pairs to indicate arrays
            int  commasSeen  = 0;
            bool bracketSeen = false;

            while (ch < nameEnd)
            {
                if (ch.Current == '[')
                {
                    ch++;
                    commasSeen  = 0;
                    bracketSeen = true;
                }
                else if (ch.Current == ']')
                {
                    if (!bracketSeen)
                    {
                        break;
                    }

                    ch++;
                    if (commasSeen == 0)
                    {
                        loadedType = loadedType.MakeArrayType();
                    }
                    else
                    {
                        loadedType = loadedType.MakeArrayType(commasSeen + 1);
                    }

                    bracketSeen = false;
                }
                else if (ch.Current == ',')
                {
                    if (!bracketSeen)
                    {
                        break;
                    }
                    ch++;
                    commasSeen++;
                }
                else
                {
                    break;
                }
            }

            // Followed by at most one & character to indicate a byref.
            if (ch < nameEnd)
            {
                if (ch.Current == '&')
                {
                    loadedType = loadedType.MakeByRefType();
                    ch++;
                }
            }

            return(loadedType);
        }
Ejemplo n.º 54
0
 static public TypeDesc MakePointerType(this TypeDesc type)
 {
     return(type.Context.GetPointerType(type));
 }
Ejemplo n.º 55
0
 static public TypeDesc MakeArrayType(this TypeDesc type)
 {
     return(type.Context.GetArrayType(type));
 }
Ejemplo n.º 56
0
        private static bool CanCastGenericParameterTo(this GenericParameterDesc thisType, TypeDesc otherType, StackOverflowProtect protect)
        {
            // A boxed variable type can be cast to any of its constraints, or object, if none are specified
            if (otherType.IsObject)
            {
                return(true);
            }

            if (thisType.HasNotNullableValueTypeConstraint &&
                otherType.IsWellKnownType(WellKnownType.ValueType))
            {
                return(true);
            }

            foreach (var typeConstraint in thisType.TypeConstraints)
            {
                if (typeConstraint.CanCastToInternal(otherType, protect))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 57
0
 public CastingPair(TypeDesc fromType, TypeDesc toType)
 {
     FromType = fromType;
     ToType   = toType;
 }
Ejemplo n.º 58
0
 static public TypeDesc MakeByRefType(this TypeDesc type)
 {
     return(type.Context.GetByRefType(type));
 }
Ejemplo n.º 59
0
        public override TypeDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
        {
            TypeDesc instantiatedParameterType = this.ParameterType.InstantiateSignature(typeInstantiation, methodInstantiation);

            return(instantiatedParameterType.Context.GetPointerType(instantiatedParameterType));
        }
Ejemplo n.º 60
0
 public override DefType[] ComputeRuntimeInterfaces(TypeDesc _type)
 {
     return(_type.BaseType.RuntimeInterfaces);
 }