public static string GetProtectedStaticsProxyName(DefType type)
 {
     string name = type.FullNativeName;
     name = name.Substring(name.IndexOf("::") + 2);
     name = name.Replace("::", "_");
     name = "Mogre::" + name + "_ProtectedStaticsProxy";
     return name;
 }
Exemple #2
0
        public RuntimeMethodDesc(bool unboxingStub, DefType owningType,
            MethodNameAndSignature nameAndSignature, int hashcode)
        {
            _owningType = owningType;
            _nameAndSignature = nameAndSignature;
            _unboxingStub = unboxingStub;
            SetHashCode(hashcode);

#if DEBUG
            DebugName = this.ToString();
#endif
        }
Exemple #3
0
        public static bool IsInternalTypeDef(DefType type)
        {
            if (!(type is DefTypeDef))
                return false;

            if (type.IsSharedPtr)
                return false;

            DefTypeDef explicitType = (type.IsNested) ? type.ParentClass.FindType<DefTypeDef>(type.Name) : type.NameSpace.FindType<DefTypeDef>(type.Name);
            if (explicitType.IsSTLContainer)
                return false;

            if (explicitType.BaseType is DefInternal)
                return true;

            return false;
        }
        public NoMetadataType(TypeSystemContext context, RuntimeTypeHandle genericTypeDefinition, DefType genericTypeDefinitionAsDefType, Instantiation instantiation, int hashcode)
        {
            _hashcode = hashcode;
            _context  = context;
            _genericTypeDefinition          = genericTypeDefinition;
            _genericTypeDefinitionAsDefType = genericTypeDefinitionAsDefType;
            if (_genericTypeDefinitionAsDefType == null)
            {
                _genericTypeDefinitionAsDefType = this;
            }
            _instantiation = instantiation;

            // Instantiation must either be:
            // Something valid (if the type is generic, or a generic type definition)
            // or Empty (if the type isn't a generic of any form)
            unsafe
            {
                Debug.Assert(((_instantiation.Length > 0) && _genericTypeDefinition.ToEETypePtr()->IsGenericTypeDefinition) ||
                             ((_instantiation.Length == 0) && !_genericTypeDefinition.ToEETypePtr()->IsGenericTypeDefinition));
            }

            // Base type is not initialized
            _baseType = this;
        }
Exemple #5
0
 protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType)
 {
     AppendName(sb, containingType);
     sb.Append('/');
     sb.Append(nestedType.Name);
 }
Exemple #6
0
 public virtual void CppCheckTypeForDependancy(DefType type)
 {
     if (!(type is DefEnum)
         && !type.IsNested
         && !type.IsPureManagedClass
         && !(type is DefInternal)
         && !type.IsValueType)
     {
         AddTypeDependancy(type);
     }
 }
		public Template(Guid id, DefType defType)
		{
			_id = id;
			_defType = defType;
		}
 public override void GetDefaultParamValueConversion(DefParam param, out string preConversion, out string conversion, out string postConversion, out DefType dependancyType)
 {
     preConversion = postConversion = "";
     dependancyType = null;
     switch (param.PassedByType)
     {
         case PassedByType.Pointer:
             if (param.DefaultValue == "NULL" || param.DefaultValue == "0")
             {
                 conversion = "nullptr";
                 return;
             }
             else
                 throw new Exception("Unexpected");
         default:
             throw new Exception("Unexpected");
     }
 }
Exemple #9
0
 public virtual void AddPragmaMakePublicForType(DefType type)
 {
     if (!PragmaMakePublicTypes.Contains(type))
         PragmaMakePublicTypes.Add(type);
 }
 /// <summary>
 /// Compute the static field layout for a DefType. Must not depend on static field layout for any other type.
 /// </summary>
 public abstract ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind);
 public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
 {
     if (type.Context.Target.Architecture == TargetArchitecture.ARM64)
     {
         return(type.InstanceFieldSize.AsInt switch
         {
             16 => ValueTypeShapeCharacteristics.Vector128Aggregate,
             _ => ValueTypeShapeCharacteristics.None
         });
Exemple #12
0
        /// <summary>
        /// Prepare the StaticGCLayout/ThreadStaticGCLayout/GcStaticDesc/ThreadStaticDesc fields by
        /// reading native layout or metadata as appropriate. This method should only be called for types which
        /// are actually to be created.
        /// </summary>
        public void PrepareStaticGCLayout()
        {
            if (!_staticGCLayoutPrepared)
            {
                _staticGCLayoutPrepared = true;
                DefType defType = TypeBeingBuilt as DefType;

                if (defType == null)
                {
                    // Array/pointer types do not have static fields
                }
                else if (defType.IsTemplateCanonical())
                {
                    // Canonical templates get their layout directly from the NativeLayoutInfo.
                    // Parse it and pull that info out here.

                    NativeParser typeInfoParser = GetParserForNativeLayoutInfo();

                    BagElementKind kind;
                    while ((kind = typeInfoParser.GetBagElementKind()) != BagElementKind.End)
                    {
                        switch (kind)
                        {
                        case BagElementKind.GcStaticDesc:
                            GcStaticDesc = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned());
                            break;

                        case BagElementKind.ThreadStaticDesc:
                            ThreadStaticDesc = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned());
                            break;

                        case BagElementKind.GcStaticEEType:
                            GcStaticEEType = NativeLayoutInfo.LoadContext.GetGCStaticInfo(typeInfoParser.GetUnsigned());
                            break;

                        default:
                            typeInfoParser.SkipInteger();
                            break;
                        }
                    }
                }
                else
                {
                    // Compute GC layout boolean array from field information.
                    IEnumerable <FieldDesc> fields             = GetFieldsForGCLayout();
                    LowLevelList <bool>     threadStaticLayout = null;
                    LowLevelList <bool>     gcStaticLayout     = null;

                    foreach (FieldDesc field in fields)
                    {
                        if (!field.IsStatic)
                        {
                            continue;
                        }

                        if (field.IsLiteral)
                        {
                            continue;
                        }

                        LowLevelList <bool> gcLayoutInfo = null;
                        if (field.IsThreadStatic)
                        {
                            if (threadStaticLayout == null)
                            {
                                threadStaticLayout = new LowLevelList <bool>();
                            }
                            gcLayoutInfo = threadStaticLayout;
                        }
                        else if (field.HasGCStaticBase)
                        {
                            if (gcStaticLayout == null)
                            {
                                gcStaticLayout = new LowLevelList <bool>();
                            }
                            gcLayoutInfo = gcStaticLayout;
                        }
                        else
                        {
                            // Non-GC static  no need to record information
                            continue;
                        }

                        TypeBuilder.GCLayout fieldGcLayout = GetFieldGCLayout(field.FieldType);
                        fieldGcLayout.WriteToBitfield(gcLayoutInfo, field.Offset.AsInt);
                    }

                    if (gcStaticLayout != null && gcStaticLayout.Count > 0)
                    {
                        StaticGCLayout = gcStaticLayout;
                    }

                    if (threadStaticLayout != null && threadStaticLayout.Count > 0)
                    {
                        ThreadStaticGCLayout = threadStaticLayout;
                    }
                }
            }
        }
Exemple #13
0
            private bool ComputeIsBlocked(EcmaType type, ModuleBlockingMode blockingMode)
            {
                // If the type is explicitly blocked, it's always blocked.
                if (type.HasCustomAttribute("System.Runtime.CompilerServices", "ReflectionBlockedAttribute"))
                {
                    return(true);
                }

                // If no blocking is applied to the module, the type is not blocked
                if (blockingMode == ModuleBlockingMode.None)
                {
                    return(false);
                }

                // <Module> type always gets metadata
                if (type.IsModuleType)
                {
                    return(false);
                }

                // The various SR types used in Resource Manager always get metadata
                if (type.Name == "SR")
                {
                    return(false);
                }

                // Event sources are not blocked
                if (type.HasCustomAttribute("System.Diagnostics.Tracing", "EventSourceAttribute"))
                {
                    return(false);
                }

                // We block everything else if the module is blocked
                if (blockingMode == ModuleBlockingMode.FullyBlocked)
                {
                    return(true);
                }

                DefType containingType = type.ContainingType;
                var     typeDefinition = type.MetadataReader.GetTypeDefinition(type.Handle);

                // [Serializable] types may be serialized by reflection-based serializers, so we need to
                // permit limited reflection over them. Details are at https://msdn.microsoft.com/en-us/library/system.serializableattribute(v=vs.110).aspx
                bool blockIfNotVisibleOrAccessible = true;

                if (type.IsSerializable)
                {
                    blockIfNotVisibleOrAccessible = false;
                }

                if (containingType == null)
                {
                    if ((typeDefinition.Attributes & TypeAttributes.Public) == 0)
                    {
                        return(blockIfNotVisibleOrAccessible);
                    }
                }
                else
                {
                    if ((typeDefinition.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic)
                    {
                        return(ComputeIsBlocked((EcmaType)containingType, blockingMode));
                    }
                    else
                    {
                        return(blockIfNotVisibleOrAccessible || ComputeIsBlocked((EcmaType)containingType, blockingMode));
                    }
                }

                return(false);
            }
Exemple #14
0
        public void VerifyInterfaces()
        {
            TypeDefinition typeDefinition = _module.MetadataReader.GetTypeDefinition(_typeDefinitionHandle);
            EcmaType       type           = (EcmaType)_module.GetType(_typeDefinitionHandle);

            if (type.IsInterface)
            {
                return;
            }

            InterfaceImplementationHandleCollection interfaceHandles = typeDefinition.GetInterfaceImplementations();
            int count = interfaceHandles.Count;

            if (count == 0)
            {
                return;
            }

            // Look for duplicates and prepare distinct list of implemented interfaces to avoid
            // subsequent error duplication
            VirtualMethodAlgorithm          virtualMethodAlg      = _typeSystemContext.GetVirtualMethodAlgorithmForType(type);
            List <InterfaceMetadataObjects> implementedInterfaces = new List <InterfaceMetadataObjects>();

            foreach (InterfaceImplementationHandle interfaceHandle in interfaceHandles)
            {
                InterfaceImplementation interfaceImplementation = _module.MetadataReader.GetInterfaceImplementation(interfaceHandle);
                DefType interfaceType = _module.GetType(interfaceImplementation.Interface) as DefType;
                if (interfaceType == null)
                {
                    ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadBadFormat, type);
                }

                InterfaceMetadataObjects imo = new InterfaceMetadataObjects
                {
                    DefType = interfaceType,
                    InterfaceImplementationHandle = interfaceHandle
                };

                if (!implementedInterfaces.Contains(imo))
                {
                    implementedInterfaces.Add(imo);
                }
                else
                {
                    VerificationError(VerifierError.InterfaceImplHasDuplicate, Format(type), Format(interfaceType));
                }
            }

            foreach (InterfaceMetadataObjects implementedInterface in implementedInterfaces)
            {
                if (!type.IsAbstract)
                {
                    // Look for missing method implementation
                    foreach (MethodDesc method in implementedInterface.DefType.GetAllMethods())
                    {
                        MethodDesc resolvedMethod = virtualMethodAlg.ResolveInterfaceMethodToVirtualMethodOnType(method, type);
                        if (resolvedMethod is null)
                        {
                            VerificationError(VerifierError.InterfaceMethodNotImplemented, Format(type), Format(implementedInterface.DefType), Format(method));
                        }
                    }
                }
            }
        }
Exemple #15
0
 private string Format(DefType interfaceTypeDef)
 {
     return(interfaceTypeDef.ToString());
 }
Exemple #16
0
        private void AddVirtualMethodUseDependencies(DependencyList dependencyList, NodeFactory factory)
        {
            DefType closestDefType = _type.GetClosestDefType();

            if (_type.RuntimeInterfaces.Length > 0 && !factory.VTable(closestDefType).HasFixedSlots)
            {
                foreach (var implementedInterface in _type.RuntimeInterfaces)
                {
                    // If the type implements ICastable, the methods are implicitly necessary
                    if (implementedInterface == factory.ICastableInterface)
                    {
                        MethodDesc isInstDecl      = implementedInterface.GetKnownMethod("IsInstanceOfInterface", null);
                        MethodDesc getImplTypeDecl = implementedInterface.GetKnownMethod("GetImplType", null);

                        MethodDesc isInstMethodImpl      = _type.ResolveInterfaceMethodTarget(isInstDecl);
                        MethodDesc getImplTypeMethodImpl = _type.ResolveInterfaceMethodTarget(getImplTypeDecl);

                        if (isInstMethodImpl != null)
                        {
                            dependencyList.Add(factory.VirtualMethodUse(isInstMethodImpl), "ICastable IsInst");
                        }
                        if (getImplTypeMethodImpl != null)
                        {
                            dependencyList.Add(factory.VirtualMethodUse(getImplTypeMethodImpl), "ICastable GetImplType");
                        }
                    }

                    // If any of the implemented interfaces have variance, calls against compatible interface methods
                    // could result in interface methods of this type being used (e.g. IEnumberable<object>.GetEnumerator()
                    // can dispatch to an implementation of IEnumerable<string>.GetEnumerator()).
                    // For now, we will not try to optimize this and we will pretend all interface methods are necessary.
                    bool allInterfaceMethodsAreImplicitlyUsed = false;
                    if (implementedInterface.HasVariance)
                    {
                        TypeDesc interfaceDefinition = implementedInterface.GetTypeDefinition();
                        for (int i = 0; i < interfaceDefinition.Instantiation.Length; i++)
                        {
                            if (((GenericParameterDesc)interfaceDefinition.Instantiation[i]).Variance != 0 &&
                                !implementedInterface.Instantiation[i].IsValueType)
                            {
                                allInterfaceMethodsAreImplicitlyUsed = true;
                                break;
                            }
                        }
                    }
                    if (!allInterfaceMethodsAreImplicitlyUsed &&
                        (_type.IsArray || _type.GetTypeDefinition() == factory.ArrayOfTEnumeratorType) &&
                        implementedInterface.HasInstantiation)
                    {
                        // NOTE: we need to also do this for generic interfaces on arrays because they have a weird casting rule
                        // that doesn't require the implemented interface to be variant to consider it castable.
                        // For value types, we only need this when the array is castable by size (int[] and ICollection<uint>),
                        // or it's a reference type (Derived[] and ICollection<Base>).
                        TypeDesc elementType = _type.IsArray ? ((ArrayType)_type).ElementType : _type.Instantiation[0];
                        allInterfaceMethodsAreImplicitlyUsed =
                            CastingHelper.IsArrayElementTypeCastableBySize(elementType) ||
                            (elementType.IsDefType && !elementType.IsValueType);
                    }

                    if (allInterfaceMethodsAreImplicitlyUsed)
                    {
                        foreach (var interfaceMethod in implementedInterface.GetAllMethods())
                        {
                            if (interfaceMethod.Signature.IsStatic)
                            {
                                continue;
                            }

                            // Generic virtual methods are tracked by an orthogonal mechanism.
                            if (interfaceMethod.HasInstantiation)
                            {
                                continue;
                            }

                            MethodDesc implMethod = closestDefType.ResolveInterfaceMethodToVirtualMethodOnType(interfaceMethod);
                            if (implMethod != null)
                            {
                                dependencyList.Add(factory.VirtualMethodUse(interfaceMethod), "Variant interface method");
                                dependencyList.Add(factory.VirtualMethodUse(implMethod), "Variant interface method");
                            }
                        }
                    }
                }
            }
        }
 protected virtual void AddNestedType(DefType nested)
 {
 }
		//If the template is null, then use the templateID
		//The caller is expected to set the TransactionScope
		public static string GetTemplateDef(Template template, Guid templateID, DefType defType)
		{
			Guid localTemplateID = template == null ? templateID : template.ID;
			string sTemplateDef = null;
			DataSet ds;
			try
			{
				switch (defType)
				{
					case DefType.NotAssigned:
						throw new Exception(string.Format("DefType not assigned for TemplateID {0}",templateID.ToString()));
					case DefType.Draft:
						ds = Data.Template.GetDraftTemplateDef(localTemplateID);
						sTemplateDef = (string)ds.Tables[0].Rows[0][Data.DataNames._C_DraftTemplateDef];
						break;
					case DefType.Final:
						ds = Data.Template.GetFinalTemplateDef(localTemplateID);
						sTemplateDef = (string)ds.Tables[0].Rows[0][Data.DataNames._C_FinalTemplateDef];
						break;
					case DefType.ManagedItem:
						if (template == null)
							throw new Exception("Failed to provide Template object for GetTemplateDef call");
						if (!template.IsManagedItem)
							throw new Exception(string.Format("Failed to cast TemplateID {0} to ManagedItem", localTemplateID.ToString()));
						ManagedItem managedItem = template as ManagedItem;
						sTemplateDef = Data.ManagedItem.GetTemplateDef(managedItem.ManagedItemID);
						break;
				}
				if (string.IsNullOrEmpty(sTemplateDef))
					return null;
			}
			catch
			{
				return null;
			}
			return sTemplateDef;
		}
 private static bool Load <T>(DefType type, out T t)
 {
     return(Load <T>(type.ToString(), out t));
 }
 public override ComputedStaticFieldLayout ComputeStaticFieldLayout(DefType type, StaticLayoutKind layoutKind)
 {
     return(_fallbackAlgorithm.ComputeStaticFieldLayout(type, layoutKind));
 }
 /// <summary>
 /// Compute the shape of a valuetype. The shape information is used to control code generation and allocation
 /// (such as vectorization, passing the valuetype by value across method calls, or boxing alignment).
 /// </summary>
 public abstract ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type);
 private static bool Save <T>(DefType type, T t)
 {
     return(Save <T>(type.ToString(), t));
 }
        public override void GetDefaultParamValueConversion(DefParam param, out string preConversion, out string conversion, out string postConversion, out DefType dependancyType)
        {
            preConversion = postConversion = "";
            dependancyType = null;
            switch (param.PassedByType)
            {
                case PassedByType.Reference:
                case PassedByType.Value:
                    conversion = param.DefaultValue.Trim();
                    if (!conversion.StartsWith("\"")
                        && conversion.Contains("::"))
                    {
                        //It's a static string of a class

                        if (conversion == "StringUtil::BLANK")
                        {
                            //Manually translate "StringUtil::BLANK" so that there's no need to wrap the StringUtil class
                            conversion = "String::Empty";
                            return;
                        }

                        string name = conversion.Substring(0, conversion.LastIndexOf("::"));
                        dependancyType = FindType<DefType>(name);
                    }
                    break;
                default:
                    throw new Exception("Unexpected");

            }
        }
        public static bool IsGeneric(this TypeDesc type)
        {
            DefType typeAsDefType = type as DefType;

            return(typeAsDefType != null && typeAsDefType.HasInstantiation);
        }
Exemple #25
0
        public bool TypeIsWrappable(DefType type)
        {
            if (type.Name.StartsWith("DLL_"))
            {
                //It's DLL function pointers of OgrePlatformManager.h
                return false;
            }

            // Get explicit type or a new type if type has ReplaceBy attribute
            type = (type.IsNested) ? type.ParentClass.FindType<DefType>(type.Name) : type.NameSpace.FindType<DefType>(type.Name);

            if (type.HasAttribute<CustomIncClassDefinitionAttribute>())
                return true;

            if (type.IsIgnored)
                return false;

            if (type.HasAttribute<WrapTypeAttribute>())
                return true;

            if (type.IsSharedPtr)
            {
                type.Attributes.Add(new WrapTypeAttribute(WrapTypes.SharedPtr));
                return true;
            }
            else if (type is DefClass)
            {
                DefClass cls = type as DefClass;
                if (cls.HasAttribute<CLRObjectAttribute>(true))
                {
                    if (cls.HasAttribute<OverridableAttribute>(true))
                        cls.Attributes.Add(new WrapTypeAttribute(WrapTypes.Overridable));
                    else
                        cls.Attributes.Add(new WrapTypeAttribute(WrapTypes.NonOverridable));
                    return true;
                }

                if (cls.IsSingleton)
                {
                    cls.Attributes.Add(new WrapTypeAttribute(WrapTypes.Singleton));
                    return true;
                }

                return false;
            }
            else if (type is DefTypeDef)
            {
                if (type.IsSTLContainer)
                {
                    foreach (ITypeMember m in (type as DefTypeDef).TypeMembers)
                    {
                        DefType mt = m.Type;
                        if (!mt.IsValueType && !mt.IsPureManagedClass
                            && !TypeIsWrappable(mt))
                            return false;
                    }

                    return true;
                }
                else if (type is DefIterator)
                {
                    if (TypeIsWrappable((type as DefIterator).TypeMembers[0].Type))
                    {
                        if ((type as DefIterator).IsConstIterator)
                        {
                            try
                            {
                                DefType notconst = type.FindType<DefType>(type.Name.Substring("Const".Length), true);
                                return false;
                            }
                            catch
                            {
                                return true;
                            }
                        }
                        else
                            return true;
                    }
                    else
                        return false;
                }
                else if ((type as DefTypeDef).BaseType is DefInternal
                         || (type as DefTypeDef).BaseType.HasAttribute<ValueTypeAttribute>())
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
        public override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type)
        {
            if (type.Context.Target.Architecture == TargetArchitecture.ARM)
            {
                unsafe
                {
                    // On ARM, the HFA type is encoded into the EEType directly
                    type.RetrieveRuntimeTypeHandleIfPossible();
                    Debug.Assert(!type.RuntimeTypeHandle.IsNull());
                    EEType *eeType = type.RuntimeTypeHandle.ToEETypePtr();

                    if (!eeType->IsHFA)
                    {
                        return(ValueTypeShapeCharacteristics.None);
                    }

                    if (eeType->RequiresAlign8)
                    {
                        return(ValueTypeShapeCharacteristics.Float64Aggregate);
                    }
                    else
                    {
                        return(ValueTypeShapeCharacteristics.Float32Aggregate);
                    }
                }
            }
            else
            {
                Debug.Assert(
                    type.Context.Target.Architecture == TargetArchitecture.X86 ||
                    type.Context.Target.Architecture == TargetArchitecture.X64);

                return(ValueTypeShapeCharacteristics.None);
            }
        }
Exemple #27
0
        public virtual void CheckTypeForDependancy(DefType type)
        {
            if (type is DefEnum
                || (!(type is IDefString) && type is DefTypeDef && (type as DefTypeDef).BaseType is DefInternal)
                || type.HasWrapType(WrapTypes.NativePtrValueType)
                || type.HasWrapType(WrapTypes.ValueType))
                AddTypeDependancy(type);
            else if (type.ParentClass != null)
                AddTypeDependancy(type.ParentClass);
            else if (type is DefTypeDef)
                CheckTypeForDependancy((type as DefTypeDef).BaseType);

            if (!type.IsNested && type is DefClass)
                AddPragmaMakePublicForType(type);
        }
 public unsafe override bool ComputeContainsGCPointers(DefType type)
 {
     return(type.RuntimeTypeHandle.ToEETypePtr()->HasGCPointers);
 }
Exemple #29
0
 public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type)
 {
     return(_metadataFieldLayoutAlgorithm);
 }
        /// <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, bool followVirtualDispatch)
        {
            TypeSystemContext context        = delegateType.Context;
            DefType           systemDelegate = 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;
                MethodDesc initMethod;

                if (!closed)
                {
                    // Open delegate to a static method
                    if (targetMethod.IsNativeCallable)
                    {
                        // If target method is native callable, create a reverse PInvoke delegate
                        initMethod  = systemDelegate.GetKnownMethod("InitializeReversePInvokeThunk", null);
                        invokeThunk = delegateInfo.Thunks[DelegateThunkKind.ReversePinvokeThunk];

                        // You might hit this when the delegate is generic: you need to make the delegate non-generic.
                        // If the code works on Project N, it's because the delegate is used in connection with
                        // AddrOf intrinsic (please validate that). We don't have the necessary AddrOf expansion in
                        // the codegen to make this work without actually constructing the delegate. You can't construct
                        // the delegate if it's generic, even on Project N.
                        // TODO: Make this throw something like "TypeSystemException.InvalidProgramException"?
                        Debug.Assert(invokeThunk != null, "Delegate with a non-native signature for a NativeCallable method");
                    }
                    else
                    {
                        initMethod  = systemDelegate.GetKnownMethod("InitializeOpenStaticThunk", null);
                        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];
                    initMethod  = systemDelegate.GetKnownMethod("InitializeClosedStaticThunk", null);
                }

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

                return(new DelegateCreationInfo(
                           factory.MethodEntrypoint(initMethod),
                           targetMethod,
                           TargetKind.ExactCallableAddress,
                           factory.MethodEntrypoint(invokeThunk)));
            }
            else
            {
                if (!closed)
                {
                    throw new NotImplementedException("Open instance delegates");
                }

                string     initializeMethodName = "InitializeClosedInstance";
                MethodDesc targetCanonMethod    = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                TargetKind kind;
                if (targetMethod.HasInstantiation)
                {
                    if (followVirtualDispatch && targetMethod.IsVirtual)
                    {
                        initializeMethodName = "InitializeClosedInstanceWithGVMResolution";
                        kind = TargetKind.MethodHandle;
                    }
                    else
                    {
                        if (targetMethod != targetCanonMethod)
                        {
                            // Closed delegates to generic instance methods need to be constructed through a slow helper that
                            // checks for the fat function pointer case (function pointer + instantiation argument in a single
                            // pointer) and injects an invocation thunk to unwrap the fat function pointer as part of
                            // the invocation if necessary.
                            initializeMethodName = "InitializeClosedInstanceSlow";
                        }

                        kind = TargetKind.ExactCallableAddress;
                    }
                }
                else
                {
                    if (followVirtualDispatch && targetMethod.IsVirtual)
                    {
                        if (targetMethod.OwningType.IsInterface)
                        {
                            kind = TargetKind.InterfaceDispatch;
                            initializeMethodName = "InitializeClosedInstanceToInterface";
                        }
                        else
                        {
                            kind         = TargetKind.VTableLookup;
                            targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                        }
                    }
                    else
                    {
                        kind         = TargetKind.CanonicalEntrypoint;
                        targetMethod = targetMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
                    }
                }

                return(new DelegateCreationInfo(
                           factory.MethodEntrypoint(systemDelegate.GetKnownMethod(initializeMethodName, null)),
                           targetMethod,
                           kind));
            }
        }
 /// <summary>
 /// This is used to set base type for generic types without metadata
 /// </summary>
 public void SetBaseType(DefType baseType)
 {
     Debug.Assert(_baseType == this || _baseType == baseType);
     _baseType = baseType;
 }
Exemple #32
0
 public bool TryGetDynamicLayout(DefType instantiatedType, out FieldAndOffset[] fieldMap)
 {
     return(_genericTypeToFieldMap.TryGetValue(instantiatedType, out fieldMap));
 }
Exemple #33
0
            protected override void AppendNameForNamespaceType(StringBuilder sb, DefType type)
            {
                switch (type.Category)
                {
                case TypeFlags.Void:
                    sb.Append("void");
                    return;

                case TypeFlags.Boolean:
                    sb.Append("bool");
                    return;

                case TypeFlags.Char:
                    sb.Append("char");
                    return;

                case TypeFlags.SByte:
                    sb.Append("int8");
                    return;

                case TypeFlags.Byte:
                    sb.Append("uint8");
                    return;

                case TypeFlags.Int16:
                    sb.Append("int16");
                    return;

                case TypeFlags.UInt16:
                    sb.Append("uint16");
                    return;

                case TypeFlags.Int32:
                    sb.Append("int32");
                    return;

                case TypeFlags.UInt32:
                    sb.Append("uint32");
                    return;

                case TypeFlags.Int64:
                    sb.Append("int64");
                    return;

                case TypeFlags.UInt64:
                    sb.Append("uint64");
                    return;

                case TypeFlags.IntPtr:
                    sb.Append("native int");
                    return;

                case TypeFlags.UIntPtr:
                    sb.Append("native uint");
                    return;

                case TypeFlags.Single:
                    sb.Append("float32");
                    return;

                case TypeFlags.Double:
                    sb.Append("float64");
                    return;
                }

                if (type.IsString)
                {
                    sb.Append("string");
                    return;
                }

                if (type.IsObject)
                {
                    sb.Append("object");
                    return;
                }

                AppendNameForNamespaceTypeWithoutAliases(sb, type);
            }
Exemple #34
0
 public FieldAndOffset[] GetOrAddDynamicLayout(DefType instantiatedType, FieldAndOffset[] fieldMap)
 {
     return(_genericTypeToFieldMap.GetOrAdd(instantiatedType, fieldMap));
 }
        /// <summary>
        /// Given a type, and vtable slot index, compute either the NativeFormatMethod that defines that vtable slot,
        /// OR the implementation function pointer if the method doesn't have sufficient metadata to be interesting
        /// to use the virtual function resolution algorithm on.
        /// </summary>
        /// <param name="type">Type on which virtual resolution is to be completed</param>
        /// <param name="vtableSlotIndex">Virtual slot index which is to be examined</param>
        /// <param name="functionPointer">If there is no corresponding method defined in metadata, this is
        /// the function pointer that should be used for calls to this vtable slot</param>
        /// <returns>MethodDesc of function that defined the slot if possible.</returns>
        private static unsafe MethodDesc ResolveVTableSlotIndexToMethodDescOrFunctionPointer(DefType type, int vtableSlotIndex, out IntPtr functionPointer)
        {
            Debug.Assert(type.RetrieveRuntimeTypeHandleIfPossible());
            Debug.Assert(type.RuntimeTypeHandle.ToEETypePtr()->NumVtableSlots > vtableSlotIndex);
            DefType definingTypeScan     = type;
            DefType previousDefiningType = null;
            EEType *typePtr      = null;
            DefType definingType = null;

            functionPointer = IntPtr.Zero;

            while (true)
            {
                definingTypeScan.RetrieveRuntimeTypeHandleIfPossible();
                Debug.Assert(!definingTypeScan.RuntimeTypeHandle.IsNull());
                typePtr = definingTypeScan.RuntimeTypeHandle.ToEETypePtr();
                if (typePtr->NumVtableSlots > vtableSlotIndex)
                {
                    previousDefiningType = definingTypeScan;
                    definingTypeScan     = definingTypeScan.BaseType;

                    // We found a slot on System.Object
                    if (definingTypeScan == null)
                    {
                        definingType = previousDefiningType;
                        break;
                    }
                }
                else
                {
                    // We've gone past the type in the type hierarchy that declared this vtable slot
                    // the defining type is the one we looked at previously
                    definingType = previousDefiningType;
                    break;
                }
            }

            // At this point, we know the type that definined the virtual slot
            // There are 4 possibilities here
            //  1. The definingType is a R2R type with full metadata. Compute the MethodDesc, by scanning the list of virtuals present in metadata
            //  2. The definingType is pregenerated, but we can go from the slot index to metadata via the runtime mapping tables. Do so, then run
            //     normal algorithm
            //  3. The definingType is pregenerated, but we cannot go from the slot index to metadata via the runtime mapping tables. There is
            //      only 1 pointer in the vtable of the most derived pregenerated type that has the same value. That's the valuable pointer.
            //  4. The definingType is pregenerated, but we cannot go from the slot index to metadata via the runtime mapping tables. There are
            //      multiple pointers in the vtable of the most derived pregenerated types which have this same value.
            //         - Take that pointer value, and attempt to resolve back to a method from the implementation. If that succeeds, then
            //           treat that as the correct vtable slot. Otherwise, return that function pointer. (This is a very rare scenario.)
            MethodDesc slotDefiningMethod = null;

            if (!IsPregeneratedOrTemplateTypeLoaded(definingType))
            {
                // Case 1

                MetadataType definingMetadataType = (MetadataType)definingType;
                int          baseTypeSlotCount    = 0;

                if (definingMetadataType.BaseType != null)
                {
                    baseTypeSlotCount = definingMetadataType.BaseType.GetRuntimeTypeHandle().ToEETypePtr()->NumVtableSlots;
                }

                int slotOnType = vtableSlotIndex - baseTypeSlotCount;
                Debug.Assert(slotOnType >= 0);

                // R2R types create new slots only for methods that are marked as NewSlot
                if (definingMetadataType.ConvertToCanonForm(CanonicalFormKind.Specific) != definingType)
                {
                    // Deal with the space reserved for the canonical dictionary
                    slotOnType--;
                }
                Debug.Assert(slotOnType >= 0);

                int currentSlot = 0;
                foreach (MethodDesc method in definingMetadataType.GetMethods())
                {
                    if (!MethodDefinesVTableSlot(method))
                    {
                        continue;
                    }

                    if (currentSlot == slotOnType)
                    {
                        Debug.Assert(VirtualMethodToSlotIndex(method) == vtableSlotIndex);
                        return(method);
                    }
                    else
                    {
                        currentSlot++;
                    }
                }

                Environment.FailFast("Unexpected failure to find virtual function that defined slot");
                return(null);
            }
            else if (TryGetVirtualMethodFromSlot(definingType, vtableSlotIndex, out slotDefiningMethod))
            {
                // Case 2
                Debug.Assert(VirtualMethodToSlotIndex(slotDefiningMethod) == vtableSlotIndex);
                return(slotDefiningMethod);
            }
            else
            {
                TypeDesc mostDerivedPregeneratedType = GetMostDerivedPregeneratedOrTemplateLoadedType(type);

                EEType *mostDerivedTypeEEType = mostDerivedPregeneratedType.GetRuntimeTypeHandle().ToEETypePtr();
                IntPtr *vtableStart           = (IntPtr *)(((byte *)mostDerivedTypeEEType) + sizeof(EEType));

                IntPtr possibleFunctionPointerReturn = vtableStart[vtableSlotIndex];
                int    functionPointerMatches        = 0;
                for (int i = 0; i < mostDerivedTypeEEType->NumVtableSlots; i++)
                {
                    if (vtableStart[i] == possibleFunctionPointerReturn)
                    {
                        functionPointerMatches++;
                    }
                }

                if (functionPointerMatches == 1)
                {
                    // Case 3
                    functionPointer = possibleFunctionPointerReturn;
                    return(null);
                }
                else
                {
                    // Case 4
                    // While this case is theoretically possible, it requires MethodImpl to MethodImpl overloading for virtual functions
                    // in the non-ready to run portions of the binary. Given our current shipping plans, as this does not occur in non-obfuscated
                    // code, we will throw NotImplementedException here.
                    // The real implementation would look something like
                    // if (!TryGetNativeFormatMethodFromFunctionPointer(possibleFunctionPointerReturn, out method))
                    // {
                    //     // this method could not have been overriden in dynamically loaded code
                    //     functionPointer = possibleFunctionPointerReturn;
                    //     return null;
                    // }
                    // else
                    // {
                    //     return VirtualFunctionAlgorithm.GetDefiningMethod(method)
                    // }
                    //
                    throw NotImplemented.ByDesign;
                }
            }
        }
Exemple #36
0
        /// <summary>
        /// If given <param name="type"/> is an <see cref="EcmaType"/> precompute its mangled type name
        /// along with all the other types from the same module as <param name="type"/>.
        /// Otherwise, it is a constructed type and to the EcmaType's mangled name we add a suffix to
        /// show what kind of constructed type it is (e.g. appending __Array for an array type).
        /// </summary>
        /// <param name="type">Type to mangled</param>
        /// <returns>Mangled name for <param name="type"/>.</returns>
        private string ComputeMangledTypeName(TypeDesc type)
        {
            if (type is EcmaType)
            {
                EcmaType ecmaType = (EcmaType)type;

                string assemblyName    = ((EcmaAssembly)ecmaType.EcmaModule).GetName().Name;
                bool   isSystemPrivate = assemblyName.StartsWith("System.Private.");

                // Abbreviate System.Private to S.P. This might conflict with user defined assembly names,
                // but we already have a problem due to running SanitizeName without disambiguating the result
                // This problem needs a better fix.
                if (isSystemPrivate && !_mangleForCplusPlus)
                {
                    assemblyName = "S.P." + assemblyName.Substring(15);
                }
                string prependAssemblyName = SanitizeName(assemblyName);

                var deduplicator = new HashSet <string>();

                // Add consistent names for all types in the module, independent on the order in which
                // they are compiled
                lock (this)
                {
                    bool isSystemModule = ecmaType.Module == ecmaType.Context.SystemModule;

                    if (!_mangledTypeNames.ContainsKey(type))
                    {
                        foreach (MetadataType t in ecmaType.EcmaModule.GetAllTypes())
                        {
                            string name = t.GetFullName();

                            // Include encapsulating type
                            DefType containingType = t.ContainingType;
                            while (containingType != null)
                            {
                                name           = containingType.GetFullName() + "_" + name;
                                containingType = containingType.ContainingType;
                            }

                            name = SanitizeName(name, true);

                            if (_mangleForCplusPlus)
                            {
                                // Always generate a fully qualified name
                                name = "::" + prependAssemblyName + "::" + name;
                            }
                            else
                            {
                                name = prependAssemblyName + "_" + name;

                                // If this is one of the well known types, use a shorter name
                                // We know this won't conflict because all the other types are
                                // prefixed by the assembly name.
                                if (isSystemModule)
                                {
                                    switch (t.Category)
                                    {
                                    case TypeFlags.Boolean: name = "Bool"; break;

                                    case TypeFlags.Byte: name = "UInt8"; break;

                                    case TypeFlags.SByte: name = "Int8"; break;

                                    case TypeFlags.UInt16: name = "UInt16"; break;

                                    case TypeFlags.Int16: name = "Int16"; break;

                                    case TypeFlags.UInt32: name = "UInt32"; break;

                                    case TypeFlags.Int32: name = "Int32"; break;

                                    case TypeFlags.UInt64: name = "UInt64"; break;

                                    case TypeFlags.Int64: name = "Int64"; break;

                                    case TypeFlags.Char: name = "Char"; break;

                                    case TypeFlags.Double: name = "Double"; break;

                                    case TypeFlags.Single: name = "Single"; break;

                                    case TypeFlags.IntPtr: name = "IntPtr"; break;

                                    case TypeFlags.UIntPtr: name = "UIntPtr"; break;

                                    default:
                                        if (t.IsObject)
                                        {
                                            name = "Object";
                                        }
                                        else if (t.IsString)
                                        {
                                            name = "String";
                                        }
                                        break;
                                    }
                                }
                            }

                            // Ensure that name is unique and update our tables accordingly.
                            name = DisambiguateName(name, deduplicator);
                            deduplicator.Add(name);
                            _mangledTypeNames = _mangledTypeNames.Add(t, name);
                        }
                    }
                }

                return(_mangledTypeNames[type]);
            }

            string mangledName;

            switch (type.Category)
            {
            case TypeFlags.Array:
            case TypeFlags.SzArray:
                mangledName = GetMangledTypeName(((ArrayType)type).ElementType) + "__";

                if (type.IsMdArray)
                {
                    mangledName += NestMangledName("ArrayRank" + ((ArrayType)type).Rank.ToStringInvariant());
                }
                else
                {
                    mangledName += NestMangledName("Array");
                }
                break;

            case TypeFlags.ByRef:
                mangledName = GetMangledTypeName(((ByRefType)type).ParameterType) + NestMangledName("ByRef");
                break;

            case TypeFlags.Pointer:
                mangledName = GetMangledTypeName(((PointerType)type).ParameterType) + NestMangledName("Pointer");
                break;

            default:
                // Case of a generic type. If `type' is a type definition we use the type name
                // for mangling, otherwise we use the mangling of the type and its generic type
                // parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_
                // in C++ compilation.
                var typeDefinition = type.GetTypeDefinition();
                if (typeDefinition != type)
                {
                    mangledName = GetMangledTypeName(typeDefinition);

                    var    inst = type.Instantiation;
                    string mangledInstantiation = "";
                    for (int i = 0; i < inst.Length; i++)
                    {
                        string instArgName = GetMangledTypeName(inst[i]);
                        if (_mangleForCplusPlus)
                        {
                            instArgName = instArgName.Replace("::", "_");
                        }
                        if (i > 0)
                        {
                            mangledInstantiation += "__";
                        }

                        mangledInstantiation += instArgName;
                    }
                    mangledName += NestMangledName(mangledInstantiation);
                }
                else if (type is IPrefixMangledMethod)
                {
                    mangledName = GetPrefixMangledMethodName((IPrefixMangledMethod)type).ToString();
                }
                else if (type is IPrefixMangledType)
                {
                    mangledName = GetPrefixMangledTypeName((IPrefixMangledType)type).ToString();
                }
                else
                {
                    mangledName = SanitizeName(((DefType)type).GetFullName(), true);
                }
                break;
            }

            lock (this)
            {
                // Ensure that name is unique and update our tables accordingly.
                if (!_mangledTypeNames.ContainsKey(type))
                {
                    _mangledTypeNames = _mangledTypeNames.Add(type, mangledName);
                }
            }

            return(mangledName);
        }
 protected virtual void AddNestedTypeBeforeMainType(DefType nested)
 {
 }
Exemple #38
0
        /// <summary>
        /// Validates that it will be possible to create an EEType for '<paramref name="type"/>'.
        /// </summary>
        public static void CheckCanGenerateEEType(NodeFactory factory, TypeDesc type)
        {
            // Don't validate generic definitons
            if (type.IsGenericDefinition)
            {
                return;
            }

            // System.__Canon or System.__UniversalCanon
            if (type.IsCanonicalDefinitionType(CanonicalFormKind.Any))
            {
                return;
            }

            // It must be possible to create an EEType for the base type of this type
            TypeDesc baseType = type.BaseType;

            if (baseType != null)
            {
                // Make sure EEType can be created for this.
                factory.NecessaryTypeSymbol(baseType);
            }

            // We need EETypes for interfaces
            foreach (var intf in type.RuntimeInterfaces)
            {
                // Make sure EEType can be created for this.
                factory.NecessaryTypeSymbol(intf);
            }

            // Validate classes, structs, enums, interfaces, and delegates
            DefType defType = type as DefType;

            if (defType != null)
            {
                // Ensure we can compute the type layout
                defType.ComputeInstanceLayout(InstanceLayoutKind.TypeAndFields);

                //
                // The fact that we generated an EEType means that someone can call RuntimeHelpers.RunClassConstructor.
                // We need to make sure this is possible.
                //
                if (factory.TypeSystemContext.HasLazyStaticConstructor(defType))
                {
                    defType.ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizesAndFields);
                }

                // Make sure instantiation length matches the expectation
                // TODO: it might be more resonable for the type system to enforce this (also for methods)
                if (defType.Instantiation.Length != defType.GetTypeDefinition().Instantiation.Length)
                {
                    throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
                }

                foreach (TypeDesc typeArg in defType.Instantiation)
                {
                    // ByRefs, pointers, function pointers, and System.Void are never valid instantiation arguments
                    if (typeArg.IsByRef || typeArg.IsPointer || typeArg.IsFunctionPointer || typeArg.IsVoid)
                    {
                        throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
                    }

                    // TODO: validate constraints
                }

                // Check the type doesn't have bogus MethodImpls or overrides and we can get the finalizer.
                defType.GetFinalizer();
            }

            // Validate parameterized types
            ParameterizedType parameterizedType = type as ParameterizedType;

            if (parameterizedType != null)
            {
                TypeDesc parameterType = parameterizedType.ParameterType;

                // Make sure EEType can be created for this.
                factory.NecessaryTypeSymbol(parameterType);

                if (parameterizedType.IsArray)
                {
                    if (parameterType.IsPointer || parameterType.IsFunctionPointer)
                    {
                        // Arrays of pointers and function pointers are not currently supported
                        throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
                    }

                    int elementSize = parameterType.GetElementSize();
                    if (elementSize >= ushort.MaxValue)
                    {
                        // Element size over 64k can't be encoded in the GCDesc
                        throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadValueClassTooLarge, parameterType);
                    }

                    if (((ArrayType)parameterizedType).Rank > 32)
                    {
                        throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadRankTooLarge, type);
                    }
                }

                // Validate we're not constructing a type over a ByRef
                if (parameterType.IsByRef)
                {
                    // CLR compat note: "ldtoken int32&&" will actually fail with a message about int32&; "ldtoken int32&[]"
                    // will fail with a message about being unable to create an array of int32&. This is a middle ground.
                    throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
                }

                // It might seem reasonable to disallow array of void, but the CLR doesn't prevent that too hard.
                // E.g. "newarr void" will fail, but "newarr void[]" or "ldtoken void[]" will succeed.
            }

            // Function pointer EETypes are not currently supported
            if (type.IsFunctionPointer)
            {
                throw new TypeSystemException.TypeLoadException(ExceptionStringID.ClassLoadGeneral, type);
            }
        }
 /// <summary>
 /// Compute the instance field layout for a DefType. Must not depend on static field layout for any other type.
 /// </summary>
 public abstract ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind);
Exemple #40
0
        /// <summary>
        /// If given <param name="type"/> is an <see cref="EcmaType"/> precompute its mangled type name
        /// along with all the other types from the same module as <param name="type"/>.
        /// Otherwise, it is a constructed type and to the EcmaType's mangled name we add a suffix to
        /// show what kind of constructed type it is (e.g. appending __Array for an array type).
        /// </summary>
        /// <param name="type">Type to mangled</param>
        /// <returns>Mangled name for <param name="type"/>.</returns>
        private string ComputeMangledTypeName(TypeDesc type)
        {
            if (type is EcmaType)
            {
                EcmaType ecmaType = (EcmaType)type;

                string prependAssemblyName = SanitizeName(((EcmaAssembly)ecmaType.EcmaModule).GetName().Name);

                var deduplicator = new HashSet <string>();

                // Add consistent names for all types in the module, independent on the order in which
                // they are compiled
                lock (this)
                {
                    if (!_mangledTypeNames.ContainsKey(type))
                    {
                        foreach (MetadataType t in ((EcmaType)type).EcmaModule.GetAllTypes())
                        {
                            string name = t.GetFullName();

                            // Include encapsulating type
                            DefType containingType = t.ContainingType;
                            while (containingType != null)
                            {
                                name           = containingType.GetFullName() + "_" + name;
                                containingType = containingType.ContainingType;
                            }

                            name = SanitizeName(name, true);
                            name = prependAssemblyName + "_" + name;

                            // Ensure that name is unique and update our tables accordingly.
                            name = DisambiguateName(name, deduplicator);
                            deduplicator.Add(name);
                            _mangledTypeNames = _mangledTypeNames.Add(t, name);
                        }
                    }
                }

                return(_mangledTypeNames[type]);
            }

            string mangledName;

            switch (type.Category)
            {
            case TypeFlags.Array:
            case TypeFlags.SzArray:
                mangledName = GetMangledTypeName(((ArrayType)type).ElementType) + "__";

                if (type.IsMdArray)
                {
                    mangledName += NestMangledName("ArrayRank" + ((ArrayType)type).Rank.ToStringInvariant());
                }
                else
                {
                    mangledName += NestMangledName("Array");
                }
                break;

            case TypeFlags.ByRef:
                mangledName = GetMangledTypeName(((ByRefType)type).ParameterType) + NestMangledName("ByRef");
                break;

            case TypeFlags.Pointer:
                mangledName = GetMangledTypeName(((PointerType)type).ParameterType) + NestMangledName("Pointer");
                break;

            default:
                // Case of a generic type. If `type' is a type definition we use the type name
                // for mangling, otherwise we use the mangling of the type and its generic type
                // parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_
                // in C++ compilation.
                var typeDefinition = type.GetTypeDefinition();
                if (typeDefinition != type)
                {
                    mangledName = GetMangledTypeName(typeDefinition);

                    var    inst = type.Instantiation;
                    string mangledInstantiation = "";
                    for (int i = 0; i < inst.Length; i++)
                    {
                        string instArgName = GetMangledTypeName(inst[i]);
                        if (i > 0)
                        {
                            mangledInstantiation += "__";
                        }

                        mangledInstantiation += instArgName;
                    }
                    mangledName += NestMangledName(mangledInstantiation);
                }
                else
                {
                    mangledName = SanitizeName(((DefType)type).GetFullName(), true);
                }
                break;
            }

            lock (this)
            {
                // Ensure that name is unique and update our tables accordingly.
                if (!_mangledTypeNames.ContainsKey(type))
                {
                    _mangledTypeNames = _mangledTypeNames.Add(type, mangledName);
                }
            }

            return(mangledName);
        }
 /// <summary>
 /// Compute whether the fields of the specified type contain a GC pointer.
 /// </summary>
 public abstract bool ComputeContainsGCPointers(DefType type);
        protected override void AddNestedType(DefType nested)
        {
            if (nested.HasWrapType(WrapTypes.NativeDirector))
            {
                //Interface and native director are already declared before the declaration of this class.
                return;
            }

            base.AddNestedType(nested);
            _wrapper.CppAddType(nested, _sb);
        }
 /// <summary>
 /// If the type has <see cref="ValueTypeShapeCharacteristics.HomogenousFloatAggregate"/> characteristic, returns
 /// the element type of the homogenous float aggregate. This will either be System.Double or System.Float.
 /// </summary>
 public abstract DefType ComputeHomogeneousFloatAggregateElementType(DefType type);
 protected override void AddNestedTypeBeforeMainType(DefType nested)
 {
     base.AddNestedType(nested);
     _wrapper.CppAddType(nested, _sb);
 }
 protected override void AddNestedType(DefType nested)
 {
     if (nested.IsSTLContainer)
     {
         _sb.AppendLine("typedef " + _t.FullNativeName + "::" + nested.Name + " " + nested.CLRName + ";");
     }
     else
         throw new Exception("Unexpected");
 }
 protected override void AddTypeDependancy(DefType type)
 {
     _wrapper.CppCheckTypeForDependancy(type);
 }
        public override void GetDefaultParamValueConversion(DefParam param, out string preConversion, out string conversion, out string postConversion, out DefType dependancyType)
        {
            preConversion = postConversion = "";
            dependancyType = null;
            if (IsVoid)
            {
                conversion = param.DefaultValue;
                return;
            }

            switch (param.PassedByType)
            {
                case PassedByType.Pointer:
                    if (!param.IsConst)
                    {
                        preConversion = FullCLRName + " out_" + param.Name + ";";
                        conversion = "out_" + param.Name;
                        return;
                    }
                    else
                    {
                        throw new Exception("Unexpected");
                    }
                default:
                    conversion = param.DefaultValue;
                    break;
            }
        }
Exemple #48
0
            protected override MethodDesc ResolveVirtualMethod(MethodDesc declMethod, DefType implType, out CORINFO_DEVIRTUALIZATION_DETAIL devirtualizationDetail)
            {
                MethodDesc result = base.ResolveVirtualMethod(declMethod, implType, out devirtualizationDetail);

                if (result != null && result.IsFinal && result.OwningType is MetadataType mdType && mdType.IsAbstract)
                {
                    // If this type is abstract check that we saw a non-abstract type deriving from it.
                    // We don't look at virtual methods introduced by abstract classes unless there's a non-abstract
                    // class that needs them (i.e. the non-abstract class doesn't immediately override them).
                    // This lets us optimize out some unused virtual method implementations.
                    // Allowing this to devirtualize would cause trouble because we didn't scan the method
                    // and expected it would be optimized out.
                    if (!_abstractButNonabstractlyOverriddenTypes.Contains(mdType.ConvertToCanonForm(CanonicalFormKind.Specific)))
                    {
                        // FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE is close enough...
                        devirtualizationDetail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE_IMPL_NOT_REFERENCEABLE;
                        return(null);
                    }
                }

                return(result);
            }
Exemple #49
0
        private void AddAttributesInType(DefType type, XmlElement elem)
        {
            foreach (XmlAttribute attr in elem.Attributes)
            {
                if (attr.Name != "name")
                    AddAttributeInHolder(type, CreateAttribute(attr));
            }

            foreach (XmlNode child in elem.ChildNodes)
            {
                if (!(child is XmlElement))
                    continue;

                if (child.Name[0] == '_')
                {
                    AddAttributeInHolder(type, CreateAttribute(child as XmlElement));
                    continue;
                }

                switch (child.Name)
                {
                    case "class":
                    case "struct":
                    case "enumeration":
                    case "typedef":
                        AddAttributesInType((type as DefClass).GetNestedType((child as XmlElement).GetAttribute("name")), child as XmlElement);
                        break;
                    case "function":
                    case "variable":
                        foreach (DefMember m in (type as DefClass).GetMembers((child as XmlElement).GetAttribute("name")))
                            AddAttributesInMember(m, child as XmlElement);
                        break;
                    default:
                        throw new Exception("Unexpected");
                }
            }
        }
 protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForDefType(DefType type)
 {
     return(_metadataRuntimeInterfacesAlgorithm);
 }
Exemple #51
0
        private void IncAddSharedPtrType(DefType type, IndentStringBuilder sb)
        {
            if (!type.Name.EndsWith("Ptr"))
                throw new Exception("SharedPtr class that doesn't have a name ending to 'Ptr'");

            string basename = null;
            if (type is DefClass)
                basename = (type as DefClass).Inherits[0];
            else
                basename = (type as DefTypeDef).BaseTypeName;

            int s = basename.IndexOf("<");
            int e = basename.LastIndexOf(">");
            string baseClass = basename.Substring(s + 1, e - s - 1).Trim();
            //string nativeClass = _nativePrefix + "::" + baseClass;
            string nativeClass = type.FindType<DefType>(baseClass).FullNativeName;

            string className = type.FullCLRName;
            if (className.Contains("::"))
                className = className.Substring(className.IndexOf("::") + 2);

            if (!type.IsNested)
            {
                PreDeclarations.Add("ref class " + type.Name + ";");
                sb.AppendIndent("public ");
            }
            else
            {
                sb.AppendIndent(Producer.GetProtectionString(type.ProtectionType) + ": ");
            }

            sb.Append("ref class " + type.Name + " : public " + baseClass + "\n");
            sb.AppendLine("{");
            sb.AppendLine("internal:");
            sb.IncreaseIndent();
            sb.AppendLine("\t" + type.FullNativeName + "* _sharedPtr;");
            sb.AppendLine();
            sb.AppendLine(type.Name + "(" + type.FullNativeName + "& sharedPtr) : " + baseClass + "( sharedPtr.getPointer() )");
            sb.AppendLine("{");
            sb.AppendLine("\t_sharedPtr = new " + type.FullNativeName + "(sharedPtr);");
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("!" + type.Name + "()");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine("if (_sharedPtr != 0)");
            sb.AppendLine("{");
            sb.AppendLine("\tdelete _sharedPtr;");
            sb.AppendLine("\t_sharedPtr = 0;");
            sb.AppendLine("}");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("~" + type.Name + "()");
            sb.AppendLine("{");
            sb.AppendLine("\tthis->!" + type.Name + "();");
            sb.AppendLine("}");
            sb.AppendLine();
            sb.DecreaseIndent();
            sb.AppendLine("public:");
            sb.IncreaseIndent();

            sb.AppendLine("DEFINE_MANAGED_NATIVE_CONVERSIONS_FOR_SHAREDPTR( " + className + " )");
            sb.AppendLine();

            if (type is DefClass)
            {
                DefClass realType = type.FindType<DefClass>(baseClass, false);
                if (realType != null && realType.BaseClass != null && realType.BaseClass.Name == "Resource")
                {
                    // For Resource subclasses (Material etc.) allow implicit conversion of ResourcePtr (i.e ResourcePtr -> MaterialPtr)

                    AddTypeDependancy(realType.BaseClass);

                    sb.AppendLine("static " + type.Name + "^ FromResourcePtr( ResourcePtr^ ptr )");
                    sb.AppendLine("{");
                    sb.AppendLine("\treturn (" + type.Name + "^) ptr;");
                    sb.AppendLine("}");
                    sb.AppendLine();

                    sb.AppendLine("static operator " + type.Name + "^ ( ResourcePtr^ ptr )");
                    sb.AppendLine("{");
                    sb.IncreaseIndent();
                    sb.AppendLine("void* castptr = dynamic_cast<" + nativeClass + "*>(ptr->_native);");
                    sb.AppendLine("if (castptr == 0) throw gcnew InvalidCastException(\"The underlying type of the ResourcePtr object is not of type " + baseClass + ".\");");
                    sb.AppendLine("return gcnew " + type.Name + "( (" + type.FullNativeName + ") *(ptr->_sharedPtr) );");
                    sb.DecreaseIndent();
                    sb.AppendLine("}");
                    sb.AppendLine();
                }
            }

            //sb.AppendLine(type.Name + "() : " + baseClass + "( (" + nativeClass + "*) 0 )");
            //sb.AppendLine("{");
            //sb.AppendLine("\t_sharedPtr = new " + type.FullNativeName + "();");
            //sb.AppendLine("}");
            //sb.AppendLine();
            sb.AppendLine(type.Name + "(" + baseClass + "^ obj) : " + baseClass + "( obj->_native )");
            sb.AppendLine("{");
            sb.AppendLine("\t_sharedPtr = new " + type.FullNativeName + "( static_cast<" + nativeClass + "*>(obj->_native) );");
            sb.AppendLine("}");
            sb.AppendLine();
            //sb.AppendLine("void Bind(" + baseClass + "^ obj)");
            //sb.AppendLine("{");
            //sb.AppendLine("\t(*_sharedPtr).bind( static_cast<" + nativeClass + "*>(obj->_native) );");
            //sb.AppendLine("}");
            //sb.AppendLine();

            sb.AppendLine("virtual bool Equals(Object^ obj) override");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine(type.Name + "^ clr = dynamic_cast<" + type.Name + "^>(obj);");
            sb.AppendLine("if (clr == CLR_NULL)");
            sb.AppendLine("{");
            sb.AppendLine("\treturn false;");
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("return (_native == clr->_native);");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine("bool Equals(" + type.Name + "^ obj)");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine("if (obj == CLR_NULL)");
            sb.AppendLine("{");
            sb.AppendLine("\treturn false;");
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("return (_native == obj->_native);");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine();

            sb.AppendLine("static bool operator == (" + type.Name + "^ val1, " + type.Name + "^ val2)");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine("if ((Object^)val1 == (Object^)val2) return true;");
            sb.AppendLine("if ((Object^)val1 == nullptr || (Object^)val2 == nullptr) return false;");
            sb.AppendLine("return (val1->_native == val2->_native);");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("static bool operator != (" + type.Name + "^ val1, " + type.Name + "^ val2)");
            sb.AppendLine("{");
            sb.AppendLine("\treturn !(val1 == val2);");
            sb.AppendLine("}");
            sb.AppendLine();

            sb.AppendLine("virtual int GetHashCode() override");
            sb.AppendLine("{");
            sb.AppendLine("\treturn reinterpret_cast<int>( _native );");
            sb.AppendLine("}");
            sb.AppendLine();

            sb.AppendLine("property IntPtr NativePtr");
            sb.AppendLine("{");
            sb.AppendLine("\tIntPtr get() { return (IntPtr)_sharedPtr; }");
            sb.AppendLine("}");
            sb.AppendLine();

            sb.AppendLine("property bool Unique");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine("bool get()");
            sb.AppendLine("{");
            sb.AppendLine("\treturn (*_sharedPtr).unique();");
            sb.AppendLine("}");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("property int UseCount");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine("int get()");
            sb.AppendLine("{");
            sb.AppendLine("\treturn (*_sharedPtr).useCount();");
            sb.AppendLine("}");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine();
            //sb.AppendLine("void SetNull()");
            //sb.AppendLine("{");
            //sb.AppendLine("\t(*_sharedPtr).setNull();");
            //sb.AppendLine("\t_native = 0;");
            //sb.AppendLine("}");
            //sb.AppendLine();
            sb.AppendLine("property bool IsNull");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine("bool get()");
            sb.AppendLine("{");
            sb.AppendLine("\treturn (*_sharedPtr).isNull();");
            sb.AppendLine("}");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.AppendLine();
            sb.AppendLine("property " + baseClass + "^ Target");
            sb.AppendLine("{");
            sb.IncreaseIndent();
            sb.AppendLine(baseClass + "^ get()");
            sb.AppendLine("{");
            sb.AppendLine("\treturn static_cast<" + nativeClass + "*>(_native);");
            sb.AppendLine("}");
            sb.DecreaseIndent();
            sb.AppendLine("}");
            sb.DecreaseIndent();
            sb.AppendLine("};\n\n");
        }
Exemple #52
0
        public void IsZeroSizedReferenceType_NonEmptyType_ReturnsFalse(string className)
        {
            DefType nonEmptyClass = _testModule.GetType("Marshalling", className);

            Assert.False(nonEmptyClass.IsZeroSizedReferenceType);
        }
Exemple #53
0
 public virtual void AddTypeDependancy(DefType type)
 {
     if (!UsedTypes.Contains(type))
         this.UsedTypes.Add(type);
 }
Exemple #54
0
        public void IsZeroSizedReferenceType_EmptyType_ReturnsTrue(string className)
        {
            DefType emptyClass = _testModule.GetType("Marshalling", className);

            Assert.True(emptyClass.IsZeroSizedReferenceType);
        }
Exemple #55
0
        public void CppAddType(DefType t, IndentStringBuilder sb)
        {
            if (t.HasAttribute<CustomCppClassDefinitionAttribute>())
            {
                string txt = t.GetAttribute<CustomCppClassDefinitionAttribute>().Text;
                sb.AppendLine(txt);
                return;
            }

            if (t is DefClass)
            {
                if (!t.HasAttribute<WrapTypeAttribute>())
                {
                    //Ignore
                }
                else
                {
                    switch (t.GetAttribute<WrapTypeAttribute>().WrapType)
                    {
                        case WrapTypes.NonOverridable:
                            new CppNonOverridableClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.Overridable:
                            new CppOverridableClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.Interface:
                            new CppOverridableClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.NativeDirector:
                            new CppNativeDirectorClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.NativePtrValueType:
                            new CppNativePtrValueClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.Singleton:
                            new CppSingletonClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.CLRHandle:
                            new CppCLRHandleClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.PlainWrapper:
                            new CppPlainWrapperClassProducer(this, t as DefClass, sb).Add();
                            break;
                    }
                }
            }
            else if (t is DefTypeDef)
            {
                DefTypeDef explicitType;

                if (t.IsUnnamedSTLContainer)
                    explicitType = t as DefTypeDef;
                else
                    explicitType = (t.IsNested) ? t.ParentClass.FindType<DefTypeDef>(t.Name) : t.NameSpace.FindType<DefTypeDef>(t.Name);

                if (explicitType.IsSTLContainer)
                {
                    CppAddSTLContainer(explicitType, sb);
                }
                else if (explicitType is DefIterator)
                {
                    CppAddIterator(explicitType as DefIterator, sb);
                }
            }
        }
        protected override void AppendNameForNestedType(StringBuilder sb, DefType nestedType, DefType containingType)
        {
            AppendName(sb, containingType);

            sb.Append('+');

            string ns = GetTypeNamespace(nestedType);

            if (ns.Length > 0)
            {
                AppendEscapedIdentifier(sb, ns);
                sb.Append('.');
            }
            AppendEscapedIdentifier(sb, GetTypeName(nestedType));
        }
Exemple #57
0
        public void IncAddType(DefType t, IndentStringBuilder sb)
        {
            if (t.HasAttribute<CustomIncClassDefinitionAttribute>())
            {
                string txt = t.GetAttribute<CustomIncClassDefinitionAttribute>().Text;
                sb.AppendLine(txt);
                return;
            }

            if (t is DefClass)
            {
                if (!t.HasAttribute<WrapTypeAttribute>())
                {
                    //Ignore
                }
                else
                {
                    switch (t.GetAttribute<WrapTypeAttribute>().WrapType)
                    {
                        case WrapTypes.NonOverridable:
                            new IncNonOverridableClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.Overridable:
                            new IncOverridableClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.NativeDirector:
                            new IncNativeDirectorClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.Interface:
                            new IncInterfaceClassProducer(this, t as DefClass, sb).Add();
                            new IncOverridableClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.Singleton:
                            new IncSingletonClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.ReadOnlyStruct:
                            new IncReadOnlyStructClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.ValueType:
                            new IncValueClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.NativePtrValueType:
                            new IncNativePtrValueClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.CLRHandle:
                            new IncCLRHandleClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.PlainWrapper:
                            new IncPlainWrapperClassProducer(this, t as DefClass, sb).Add();
                            break;
                        case WrapTypes.SharedPtr:
                            IncAddSharedPtrType(t, sb);
                            break;
                    }
                }
            }
            else if (t is DefEnum)
            {
                IncAddEnum(t as DefEnum, sb);
            }
            else if (t is DefTypeDef)
            {
                DefTypeDef explicitType;

                if (t.IsUnnamedSTLContainer)
                    explicitType = t as DefTypeDef;
                else
                    explicitType = (t.IsNested) ? t.ParentClass.FindType<DefTypeDef>(t.Name) : t.NameSpace.FindType<DefTypeDef>(t.Name);

                if (t.HasWrapType(WrapTypes.SharedPtr))
                {
                    IncAddSharedPtrType(t, sb);
                }
                else if (explicitType.IsSTLContainer)
                {
                    IncAddSTLContainer(explicitType, sb);
                }
                else if (explicitType is DefIterator)
                {
                    IncAddIterator(explicitType as DefIterator, sb);
                }
                else if (explicitType.BaseType is DefInternal)
                {
                    IncAddInternalTypeDef(explicitType, sb);
                }
                else if (explicitType.BaseType.HasAttribute<ValueTypeAttribute>())
                {
                    IncAddValueTypeTypeDef(explicitType, sb);
                }
            }
        }
 private string GetTypeNamespace(DefType type)
 {
     return(type.Namespace);
 }
Exemple #59
0
 protected virtual void AddTypeDependancy(DefType type)
 {
 }
 protected virtual void CheckTypeForDependancy(DefType type)
 {
     _wrapper.CheckTypeForDependancy(type);
 }