public void Add(CorInfoIntrinsics id, string methodName, string typeNamespace, string typeName)
            {
                var entry = new IntrinsicEntry();

                entry.Id                = id;
                entry.Key.MethodName    = methodName;
                entry.Key.TypeNamespace = typeNamespace;
                entry.Key.TypeName      = typeName;
                AddOrGetExisting(entry);
            }
Esempio n. 2
0
        private CorInfoIntrinsics getIntrinsicID(MethodDesc method, byte *pMustExpand)
        {
            if (pMustExpand != null)
            {
                *pMustExpand = 0;
            }

            Debug.Assert(method.IsIntrinsic);

            IntrinsicKey key = new IntrinsicKey();

            key.MethodName = method.Name;

            var metadataType = method.OwningType as MetadataType;

            if (metadataType != null)
            {
                key.TypeNamespace = metadataType.Namespace;
                key.TypeName      = metadataType.Name;
            }

            IntrinsicEntry entry;

            if (!s_IntrinsicHashtable.TryGetValue(key, out entry))
            {
                return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
            }

            // Some intrinsics need further disambiguation
            CorInfoIntrinsics id = entry.Id;

            switch (id)
            {
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Abs:
            {
                // RyuJIT handles floating point overloads only
                var returnTypeCategory = method.Signature.ReturnType.Category;
                if (returnTypeCategory != TypeFlags.Double && returnTypeCategory != TypeFlags.Single)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }
            }
            break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Address:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Set:
                if (!method.OwningType.IsArray)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }
                break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32:
            {
                // RyuJIT handles int32 and int64 overloads only
                var returnTypeCategory = method.Signature.ReturnType.Category;
                if (returnTypeCategory != TypeFlags.Int32 && returnTypeCategory != TypeFlags.Int64 && returnTypeCategory != TypeFlags.IntPtr)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }

                // int64 overloads have different ids
                if (returnTypeCategory == TypeFlags.Int64)
                {
                    Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd64);
                    Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg64);
                    Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg64);
                    id = (CorInfoIntrinsics)((int)id + 1);
                }
            }
            break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_RTH_GetValueInternal:
#if !READYTORUN
            case CorInfoIntrinsics.CORINFO_INTRINSIC_InitializeArray:
#endif
            case CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Ctor:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Value:
                if (pMustExpand != null)
                {
                    *pMustExpand = 1;
                }
                break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle:
                if (pMustExpand != null)
                {
                    *pMustExpand = 1;
                }
                break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_Span_GetItem:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_ReadOnlySpan_GetItem:
            {
                // RyuJIT handles integer overload only
                var argumentTypeCategory = method.Signature[0].Category;
                if (argumentTypeCategory != TypeFlags.Int32)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }
            }
            break;

            default:
                break;
            }

            return(id);
        }
        private CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_STRUCT_ *ftn)
        {
            var method = HandleToObject(ftn);

            Debug.Assert(method.IsIntrinsic);

            IntrinsicKey key = new IntrinsicKey();

            key.MethodName = method.Name;

            var metadataType = method.OwningType as MetadataType;

            if (metadataType != null)
            {
                key.TypeNamespace = metadataType.Namespace;
                key.TypeName      = metadataType.Name;
            }

            IntrinsicEntry entry;

            if (!s_IntrinsicHashtable.TryGetValue(key, out entry))
            {
                return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
            }

            // Some intrinsics need further disambiguation
            CorInfoIntrinsics id = entry.Id;

            switch (id)
            {
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Abs:
            {
                // RyuJIT handles floating point overloads only
                var returnTypeCategory = method.Signature.ReturnType.Category;
                if (returnTypeCategory != TypeFlags.Double && returnTypeCategory != TypeFlags.Single)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }
            }
            break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Address:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Set:
                if (!method.OwningType.IsArray)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }
                break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32:
            {
                // RyuJIT handles int32 and int64 overloads only
                var returnTypeCategory = method.Signature.ReturnType.Category;
                if (returnTypeCategory != TypeFlags.Int32 && returnTypeCategory != TypeFlags.Int64 && returnTypeCategory != TypeFlags.IntPtr)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }

                // int64 overloads have different ids
                if (returnTypeCategory == TypeFlags.Int64)
                {
                    Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd64);
                    Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg64);
                    Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg64);
                    id = (CorInfoIntrinsics)((int)id + 1);
                }
            }
            break;

            default:
                break;
            }

            return(id);
        }
        private CorInfoIntrinsics getIntrinsicID(MethodDesc method, byte *pMustExpand)
        {
            if (pMustExpand != null)
            {
                *pMustExpand = 0;
            }

            Debug.Assert(method.IsIntrinsic);

            IntrinsicKey key = new IntrinsicKey();

            key.MethodName = method.Name;

            var metadataType = method.OwningType as MetadataType;

            if (metadataType != null)
            {
                key.TypeNamespace = metadataType.Namespace;
                key.TypeName      = metadataType.Name;
            }

            IntrinsicEntry entry;

            if (!s_IntrinsicHashtable.TryGetValue(key, out entry))
            {
                return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
            }

            // Some intrinsics need further disambiguation
            CorInfoIntrinsics id = entry.Id;

            switch (id)
            {
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Get:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Address:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_Array_Set:
                if (!method.OwningType.IsArray)
                {
                    return(CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal);
                }
                break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_RTH_GetValueInternal:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Ctor:
            case CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Value:
                if (pMustExpand != null)
                {
                    *pMustExpand = 1;
                }
                break;

            case CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle:
                if (pMustExpand != null)
                {
                    *pMustExpand = 1;
                }
                break;

            default:
                break;
            }

            return(id);
        }