Example #1
0
        public static EcmaModule Create(TypeSystemContext context, PEReader peReader, PdbSymbolReader pdbReader)
        {
            MetadataReader metadataReader = CreateMetadataReader(context, peReader);

            if (metadataReader.IsAssembly)
                return new EcmaAssembly(context, peReader, metadataReader, pdbReader);
            else
                return new EcmaModule(context, peReader, metadataReader, pdbReader);
        }
Example #2
0
        /// <summary>
        /// Returns JIT helper entrypoint. JIT helpers can be either implemented by entrypoint with given mangled name or
        /// by a method in class library.
        /// </summary>
        public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, out string mangledName, out MethodDesc methodDesc)
        {
            mangledName = null;
            methodDesc  = null;

            switch (id)
            {
            case ReadyToRunHelper.Throw:
                mangledName = "RhpThrowEx";
                break;

            case ReadyToRunHelper.Rethrow:
                mangledName = "RhpRethrow";
                break;

            case ReadyToRunHelper.Overflow:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowOverflowException");
                break;

            case ReadyToRunHelper.RngChkFail:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowIndexOutOfRangeException");
                break;

            case ReadyToRunHelper.FailFast:
                mangledName = "__fail_fast";     // TODO: Report stack buffer overrun
                break;

            case ReadyToRunHelper.ThrowNullRef:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowNullReferenceException");
                break;

            case ReadyToRunHelper.ThrowDivZero:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowDivideByZeroException");
                break;

            case ReadyToRunHelper.ThrowArgumentOutOfRange:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowArgumentOutOfRangeException");
                break;

            case ReadyToRunHelper.ThrowArgument:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowArgumentException");
                break;

            case ReadyToRunHelper.ThrowPlatformNotSupported:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowPlatformNotSupportedException");
                break;

            case ReadyToRunHelper.ThrowNotImplemented:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowNotImplementedException");
                break;

            case ReadyToRunHelper.DebugBreak:
                mangledName = "RhDebugBreak";
                break;

            case ReadyToRunHelper.WriteBarrier:
                mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpAssignRefArm64" : "RhpAssignRef";
                break;

            case ReadyToRunHelper.CheckedWriteBarrier:
                mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpCheckedAssignRefArm64" : "RhpCheckedAssignRef";
                break;

            case ReadyToRunHelper.ByRefWriteBarrier:
                mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpByRefAssignRefArm64" : "RhpByRefAssignRef";
                break;

            case ReadyToRunHelper.WriteBarrier_EAX:
                mangledName = "RhpAssignRefEAX";
                break;

            case ReadyToRunHelper.WriteBarrier_ECX:
                mangledName = "RhpAssignRefECX";
                break;

            case ReadyToRunHelper.CheckedWriteBarrier_EAX:
                mangledName = "RhpCheckedAssignRefEAX";
                break;

            case ReadyToRunHelper.CheckedWriteBarrier_ECX:
                mangledName = "RhpCheckedAssignRefECX";
                break;

            case ReadyToRunHelper.Box:
            case ReadyToRunHelper.Box_Nullable:
                mangledName = "RhBox";
                break;

            case ReadyToRunHelper.Unbox:
                mangledName = "RhUnbox2";
                break;

            case ReadyToRunHelper.Unbox_Nullable:
                mangledName = "RhUnboxNullable";
                break;

            case ReadyToRunHelper.NewMultiDimArr_NonVarArg:
                methodDesc = context.GetHelperEntryPoint("ArrayHelpers", "NewObjArray");
                break;

            case ReadyToRunHelper.NewArray:
                mangledName = "RhNewArray";
                break;

            case ReadyToRunHelper.NewObject:
                mangledName = "RhNewObject";
                break;

            case ReadyToRunHelper.Stelem_Ref:
                mangledName = "RhpStelemRef";
                break;

            case ReadyToRunHelper.Ldelema_Ref:
                mangledName = "RhpLdelemaRef";
                break;

            case ReadyToRunHelper.MemCpy:
                mangledName = "memcpy";     // TODO: Null reference handling
                break;

            case ReadyToRunHelper.MemSet:
                mangledName = "memset";     // TODO: Null reference handling
                break;

            case ReadyToRunHelper.GetRuntimeTypeHandle:
                methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeTypeHandle");
                break;

            case ReadyToRunHelper.GetRuntimeType:
                methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeType");
                break;

            case ReadyToRunHelper.GetRuntimeMethodHandle:
                methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeMethodHandle");
                break;

            case ReadyToRunHelper.GetRuntimeFieldHandle:
                methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeFieldHandle");
                break;

            case ReadyToRunHelper.AreTypesEquivalent:
                mangledName = "RhTypeCast_AreTypesEquivalent";
                break;

            case ReadyToRunHelper.Lng2Dbl:
                mangledName = "RhpLng2Dbl";
                break;

            case ReadyToRunHelper.ULng2Dbl:
                mangledName = "RhpULng2Dbl";
                break;

            case ReadyToRunHelper.Dbl2Lng:
                mangledName = "RhpDbl2Lng";
                break;

            case ReadyToRunHelper.Dbl2ULng:
                mangledName = "RhpDbl2ULng";
                break;

            case ReadyToRunHelper.Dbl2Int:
                mangledName = "RhpDbl2Int";
                break;

            case ReadyToRunHelper.Dbl2UInt:
                mangledName = "RhpDbl2UInt";
                break;

            case ReadyToRunHelper.Dbl2IntOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2IntOvf");
                break;

            case ReadyToRunHelper.Dbl2UIntOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2UIntOvf");
                break;

            case ReadyToRunHelper.Dbl2LngOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2LngOvf");
                break;

            case ReadyToRunHelper.Dbl2ULngOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2ULngOvf");
                break;

            case ReadyToRunHelper.DblRem:
                mangledName = "RhpDblRem";
                break;

            case ReadyToRunHelper.FltRem:
                mangledName = "RhpFltRem";
                break;

            case ReadyToRunHelper.DblRound:
                mangledName = "RhpDblRound";
                break;

            case ReadyToRunHelper.FltRound:
                mangledName = "RhpFltRound";
                break;

            case ReadyToRunHelper.LMul:
                mangledName = "RhpLMul";
                break;

            case ReadyToRunHelper.LMulOfv:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "LMulOvf");
                break;

            case ReadyToRunHelper.ULMulOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULMulOvf");
                break;

            case ReadyToRunHelper.Mod:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "IMod");
                break;

            case ReadyToRunHelper.UMod:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "UMod");
                break;

            case ReadyToRunHelper.ULMod:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULMod");
                break;

            case ReadyToRunHelper.LMod:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "LMod");
                break;

            case ReadyToRunHelper.Div:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "IDiv");
                break;

            case ReadyToRunHelper.UDiv:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "UDiv");
                break;

            case ReadyToRunHelper.ULDiv:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "ULDiv");
                break;

            case ReadyToRunHelper.LDiv:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "LDiv");
                break;

            case ReadyToRunHelper.LRsz:
                mangledName = "RhpLRsz";
                break;

            case ReadyToRunHelper.LRsh:
                mangledName = "RhpLRsh";
                break;

            case ReadyToRunHelper.LLsh:
                mangledName = "RhpLLsh";
                break;

            case ReadyToRunHelper.PInvokeBegin:
                mangledName = "RhpPInvoke";
                break;

            case ReadyToRunHelper.PInvokeEnd:
                mangledName = "RhpPInvokeReturn";
                break;

            case ReadyToRunHelper.ReversePInvokeEnter:
                mangledName = "RhpReversePInvoke2";
                break;

            case ReadyToRunHelper.ReversePInvokeExit:
                mangledName = "RhpReversePInvokeReturn2";
                break;

            case ReadyToRunHelper.CheckCastAny:
                mangledName = "RhTypeCast_CheckCast";
                break;

            case ReadyToRunHelper.CheckInstanceAny:
                mangledName = "RhTypeCast_IsInstanceOf";
                break;

            case ReadyToRunHelper.CheckCastInterface:
                mangledName = "RhTypeCast_CheckCastInterface";
                break;

            case ReadyToRunHelper.CheckInstanceInterface:
                mangledName = "RhTypeCast_IsInstanceOfInterface";
                break;

            case ReadyToRunHelper.CheckCastClass:
                mangledName = "RhTypeCast_CheckCastClass";
                break;

            case ReadyToRunHelper.CheckInstanceClass:
                mangledName = "RhTypeCast_IsInstanceOfClass";
                break;

            case ReadyToRunHelper.CheckCastArray:
                mangledName = "RhTypeCast_CheckCastArray";
                break;

            case ReadyToRunHelper.CheckInstanceArray:
                mangledName = "RhTypeCast_IsInstanceOfArray";
                break;

            case ReadyToRunHelper.MonitorEnter:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorEnter");
                break;

            case ReadyToRunHelper.MonitorExit:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorExit");
                break;

            case ReadyToRunHelper.MonitorEnterStatic:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorEnterStatic");
                break;

            case ReadyToRunHelper.MonitorExitStatic:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorExitStatic");
                break;

            case ReadyToRunHelper.GVMLookupForSlot:
                methodDesc = context.SystemModule.GetKnownType("System.Runtime", "TypeLoaderExports").GetKnownMethod("GVMLookupForSlot", null);
                break;

            case ReadyToRunHelper.TypeHandleToRuntimeType:
                methodDesc = context.GetHelperEntryPoint("TypedReferenceHelpers", "TypeHandleToRuntimeTypeMaybeNull");
                break;

            case ReadyToRunHelper.GetRefAny:
                methodDesc = context.GetHelperEntryPoint("TypedReferenceHelpers", "GetRefAny");
                break;

            case ReadyToRunHelper.TypeHandleToRuntimeTypeHandle:
                methodDesc = context.GetHelperEntryPoint("TypedReferenceHelpers", "TypeHandleToRuntimeTypeHandleMaybeNull");
                break;

            default:
                throw new NotImplementedException(id.ToString());
            }
        }
Example #3
0
        /// <summary>
        /// Returns JIT helper entrypoint. JIT helpers can be either implemented by entrypoint with given mangled name or
        /// by a method in class library.
        /// </summary>
        static public void GetEntryPoint(TypeSystemContext context, JitHelperId id, out string mangledName, out MethodDesc methodDesc)
        {
            mangledName = null;
            methodDesc  = null;

            switch (id)
            {
            case JitHelperId.Throw:
                mangledName = "RhpThrowEx";
                break;

            case JitHelperId.Rethrow:
                mangledName = "RhpRethrow";
                break;

            case JitHelperId.Overflow:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowOverflowException");
                break;

            case JitHelperId.RngChkFail:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowIndexOutOfRangeException");
                break;

            case JitHelperId.FailFast:
                mangledName = "__fail_fast";     // TODO: Report stack buffer overrun
                break;

            case JitHelperId.ThrowNullRef:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowNullReferenceException");
                break;

            case JitHelperId.ThrowDivZero:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowDivideByZeroException");
                break;

            case JitHelperId.WriteBarrier:
                mangledName = "RhpAssignRef";
                break;

            case JitHelperId.CheckedWriteBarrier:
                mangledName = "RhpCheckedAssignRef";
                break;

            case JitHelperId.ByRefWriteBarrier:
                mangledName = "RhpByRefAssignRef";
                break;

            case JitHelperId.NewMultiDimArr:
                mangledName = "RhNewMDArray";
                break;

            case JitHelperId.Stelem_Ref:
                mangledName = "RhpStelemRef";
                break;

            case JitHelperId.Ldelema_Ref:
                mangledName = "RhpLdelemaRef";
                break;

            case JitHelperId.MemCpy:
                mangledName = "memcpy";     // TODO: Null reference handling
                break;

            case JitHelperId.MemSet:
                mangledName = "memset";     // TODO: Null reference handling
                break;

            case JitHelperId.GetRuntimeTypeHandle:     // TODO: Reflection
            case JitHelperId.GetRuntimeMethodHandle:
            case JitHelperId.GetRuntimeFieldHandle:
                mangledName = "__fail_fast";
                break;

            default:
                throw new NotImplementedException(id.ToString());
            }
        }
 public CustomCanonResolver(TypeSystemContext wrappedContext)
 {
     _canonModule     = new CanonModule(wrappedContext);
     _canonModuleName = _canonModule.GetName();
     _wrappedResolver = wrappedContext;
 }
        /// <summary>
        /// Parse MIbcGroup method and return enumerable of MethodProfileData
        ///
        /// Like the AssemblyDictionary method, data is encoded via IL instructions. The format is
        ///
        /// ldtoken methodInProfileData
        /// Any series of instructions that does not include pop. Expansion data is encoded via ldstr "id"
        /// followed by a expansion specific sequence of il opcodes.
        /// pop
        /// {Repeat N times for N methods described}
        ///
        /// Extensions supported with current parser:
        ///
        /// ldstr "ExclusiveWeight"
        /// Any ldc.i4 or ldc.r4 or ldc.r8 instruction to indicate the exclusive weight
        ///
        /// ldstr "WeightedCallData"
        /// ldc.i4 <Count of methods called>
        /// Repeat <Count of methods called times>
        ///  ldtoken <Method called from this method>
        ///  ldc.i4 <Weight associated with calling the <Method called from this method>>
        ///
        /// This format is designed to be extensible to hold more data as we add new per method profile data without breaking existing parsers.
        /// </summary>
        static IEnumerable <MethodProfileData> ReadMIbcGroup(TypeSystemContext tsc, EcmaMethod method)
        {
            EcmaMethodIL             ilBody           = EcmaMethodIL.Create(method);
            MetadataLoaderForPgoData metadataLoader   = new MetadataLoaderForPgoData(ilBody);
            ILReader            ilReader              = new ILReader(ilBody.GetILBytes());
            object              methodInProgress      = null;
            object              metadataNotResolvable = new object();
            object              metadataObject        = null;
            MibcGroupParseState state            = MibcGroupParseState.LookingForNextMethod;
            int    intValue                      = 0;
            int    weightedCallGraphSize         = 0;
            int    profileEntryFound             = 0;
            double exclusiveWeight               = 0;
            Dictionary <MethodDesc, int> weights = null;
            bool        processIntValue          = false;
            List <long> instrumentationDataLongs = null;

            PgoSchemaElem[] pgoSchemaData = null;

            while (ilReader.HasNext)
            {
                ILOpcode opcode = ilReader.ReadILOpcode();
                processIntValue = false;
                switch (opcode)
                {
                case ILOpcode.ldtoken:
                {
                    int token = ilReader.ReadILToken();
                    if (state == MibcGroupParseState.ProcessingInstrumentationData)
                    {
                        instrumentationDataLongs.Add(token);
                    }
                    else
                    {
                        metadataObject = null;
                        try
                        {
                            metadataObject = ilBody.GetObject(token, NotFoundBehavior.ReturnNull);
                            if (metadataObject == null)
                            {
                                metadataObject = metadataNotResolvable;
                            }
                        }
                        catch (TypeSystemException)
                        {
                            // The method being referred to may be missing. In that situation,
                            // use the metadataNotResolvable sentinel to indicate that this record should be ignored
                            metadataObject = metadataNotResolvable;
                        }
                        switch (state)
                        {
                        case MibcGroupParseState.ProcessingCallgraphToken:
                            state = MibcGroupParseState.ProcessingCallgraphWeight;
                            break;

                        case MibcGroupParseState.LookingForNextMethod:
                            methodInProgress = metadataObject;
                            state            = MibcGroupParseState.LookingForOptionalData;
                            break;

                        default:
                            state = MibcGroupParseState.LookingForOptionalData;
                            break;
                        }
                    }
                }
                break;

                case ILOpcode.ldc_r4:
                {
                    float fltValue = ilReader.ReadILFloat();

                    switch (state)
                    {
                    case MibcGroupParseState.ProcessingExclusiveWeight:
                        exclusiveWeight = fltValue;
                        state           = MibcGroupParseState.LookingForOptionalData;
                        break;

                    default:
                        state = MibcGroupParseState.LookingForOptionalData;
                        break;
                    }

                    break;
                }

                case ILOpcode.ldc_r8:
                {
                    double dblValue = ilReader.ReadILDouble();

                    switch (state)
                    {
                    case MibcGroupParseState.ProcessingExclusiveWeight:
                        exclusiveWeight = dblValue;
                        state           = MibcGroupParseState.LookingForOptionalData;
                        break;

                    default:
                        state = MibcGroupParseState.LookingForOptionalData;
                        break;
                    }
                    break;
                }

                case ILOpcode.ldc_i4_0:
                    intValue        = 0;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_1:
                    intValue        = 1;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_2:
                    intValue        = 2;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_3:
                    intValue        = 3;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_4:
                    intValue        = 4;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_5:
                    intValue        = 5;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_6:
                    intValue        = 6;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_7:
                    intValue        = 7;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_8:
                    intValue        = 8;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_m1:
                    intValue        = -1;
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4_s:
                    intValue        = (sbyte)ilReader.ReadILByte();
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i4:
                    intValue        = (int)ilReader.ReadILUInt32();
                    processIntValue = true;
                    break;

                case ILOpcode.ldc_i8:
                    if (state == MibcGroupParseState.ProcessingInstrumentationData)
                    {
                        instrumentationDataLongs.Add((long)ilReader.ReadILUInt64());
                    }
                    break;

                case ILOpcode.ldstr:
                {
                    int    userStringToken  = ilReader.ReadILToken();
                    string optionalDataName = (string)ilBody.GetObject(userStringToken);
                    switch (optionalDataName)
                    {
                    case "ExclusiveWeight":
                        state = MibcGroupParseState.ProcessingExclusiveWeight;
                        break;

                    case "WeightedCallData":
                        state = MibcGroupParseState.ProcessingCallgraphCount;
                        break;

                    case "InstrumentationDataStart":
                        state = MibcGroupParseState.ProcessingInstrumentationData;
                        instrumentationDataLongs = new List <long>();
                        break;

                    case "InstrumentationDataEnd":
                        if (instrumentationDataLongs != null)
                        {
                            instrumentationDataLongs.Add(2);             // MarshalMask 2 (Type)
                            instrumentationDataLongs.Add(0);             // PgoInstrumentationKind.Done (0)
                            pgoSchemaData = PgoProcessor.ParsePgoData <TypeSystemEntityOrUnknown>(metadataLoader, instrumentationDataLongs, false).ToArray();
                        }
                        state = MibcGroupParseState.LookingForOptionalData;
                        break;

                    default:
                        state = MibcGroupParseState.LookingForOptionalData;
                        break;
                    }
                }
                break;

                case ILOpcode.pop:
                    if (methodInProgress != metadataNotResolvable)
                    {
                        profileEntryFound++;
                        if (exclusiveWeight == 0)
                        {
                            // If no exclusive weight is found assign a non zero value that assumes the order in the pgo file is significant.
                            exclusiveWeight = Math.Min(1000000.0 - profileEntryFound, 0.0) / 1000000.0;
                        }
                        if (methodInProgress != null)
                        {
                            // If the method being loaded didn't have meaningful input, skip
                            MethodProfileData mibcData = new MethodProfileData((MethodDesc)methodInProgress, MethodProfilingDataFlags.ReadMethodCode, exclusiveWeight, weights, 0xFFFFFFFF, pgoSchemaData);
                            yield return(mibcData);
                        }
                        state                    = MibcGroupParseState.LookingForNextMethod;
                        exclusiveWeight          = 0;
                        weights                  = null;
                        instrumentationDataLongs = null;
                        pgoSchemaData            = null;
                    }
                    methodInProgress = null;
                    break;

                default:
                    state = MibcGroupParseState.LookingForOptionalData;
                    ilReader.Skip(opcode);
                    break;
                }

                if (processIntValue)
                {
                    switch (state)
                    {
                    case MibcGroupParseState.ProcessingExclusiveWeight:
                        exclusiveWeight = intValue;
                        state           = MibcGroupParseState.LookingForOptionalData;
                        break;

                    case MibcGroupParseState.ProcessingCallgraphCount:
                        weightedCallGraphSize = intValue;
                        weights = new Dictionary <MethodDesc, int>();
                        if (weightedCallGraphSize > 0)
                        {
                            state = MibcGroupParseState.ProcessingCallgraphToken;
                        }
                        else
                        {
                            state = MibcGroupParseState.LookingForOptionalData;
                        }
                        break;

                    case MibcGroupParseState.ProcessingCallgraphWeight:
                        if (metadataObject != metadataNotResolvable)
                        {
                            weights.Add((MethodDesc)metadataObject, intValue);
                        }
                        weightedCallGraphSize--;
                        if (weightedCallGraphSize > 0)
                        {
                            state = MibcGroupParseState.ProcessingCallgraphToken;
                        }
                        else
                        {
                            state = MibcGroupParseState.LookingForOptionalData;
                        }
                        break;

                    case MibcGroupParseState.ProcessingInstrumentationData:
                        instrumentationDataLongs.Add(intValue);
                        break;

                    default:
                        state = MibcGroupParseState.LookingForOptionalData;
                        instrumentationDataLongs = null;
                        break;
                    }
                }
            }
        }
 public static bool IsSpecialUnboxingThunkTargetMethod(this TypeSystemContext context, MethodDesc method)
 {
     return(false);
 }
Example #7
0
        private static TypeDesc GetTypeThatMeetsConstraints(GenericParameterDesc genericParam, bool allowCanon)
        {
            TypeSystemContext context = genericParam.Context;

            // Universal canon is the best option if it's supported
            if (allowCanon && context.SupportsUniversalCanon)
            {
                return(context.UniversalCanonType);
            }

            // Not nullable type is the only thing where we can't substitute reference types
            GenericConstraints constraints = genericParam.Constraints;

            if ((constraints & GenericConstraints.NotNullableValueTypeConstraint) != 0)
            {
                return(null);
            }

            // If canon is allowed, we can use that
            if (allowCanon && context.SupportsCanon)
            {
                foreach (var c in genericParam.TypeConstraints)
                {
                    // Could be e.g. "where T : U"
                    // We could try to dig into the U and solve it, but that just opens us up to
                    // recursion and it's just not worth it.
                    if (c.IsSignatureVariable)
                    {
                        return(null);
                    }

                    if (!c.IsGCPointer)
                    {
                        return(null);
                    }
                }

                return(genericParam.Context.CanonType);
            }

            // If canon is not allowed, we're limited in our choices.
            TypeDesc constrainedType = null;

            foreach (var c in genericParam.TypeConstraints)
            {
                // Can't do multiple constraints
                if (constrainedType != null)
                {
                    return(null);
                }

                // Could be e.g. "where T : IFoo<U>" or "where T : U"
                if (c.ContainsSignatureVariables())
                {
                    return(null);
                }

                // If there's unimplemented static abstract methods, this is not a suitable instantiation.
                // We shortcut to look for any static virtuals. It matches what Roslyn does for error CS8920.
                // Once TypeSystemConstraintsHelpers is updated to check constraints around static virtuals,
                // we could dispatch there instead.
                if (c.IsInterface)
                {
                    if (HasStaticVirtualMethods(c))
                    {
                        return(null);
                    }

                    foreach (DefType intface in c.RuntimeInterfaces)
                    {
                        if (HasStaticVirtualMethods(intface))
                        {
                            return(null);
                        }
                    }
Example #8
0
 public EcmaAssembly(TypeSystemContext context, PEReader peReader, MetadataReader metadataReader)
     : base(context, peReader, metadataReader)
 {
     _assemblyDefinition = metadataReader.GetAssemblyDefinition();
 }
Example #9
0
 public static bool IsSystemGuid(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "Guid"));
 }
Example #10
0
 public static bool IsSystemDecimal(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "Decimal"));
 }
Example #11
0
 public static bool IsStringBuilder(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System.Text", "StringBuilder"));
 }
Example #12
0
 public static bool IsSystemDateTime(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "DateTime"));
 }
Example #13
0
 public static bool IsHandleRef(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System.Runtime.InteropServices", "HandleRef"));
 }
Example #14
0
 public static bool IsCriticalHandle(TypeSystemContext context, TypeDesc type)
 {
     return(IsOrDerivesFromType(type, GetCriticalHandle(context)));
 }
 public MultiFileSharedCompilationModuleGroup(TypeSystemContext context, IEnumerable <ModuleDesc> compilationModuleSet)
     : base(context, compilationModuleSet)
 {
 }
Example #16
0
 internal EcmaModule(TypeSystemContext context, PEReader peReader, MetadataReader metadataReader, PdbSymbolReader pdbReader)
     : this(context, peReader, metadataReader)
 {
     PdbReader = pdbReader;
 }
Example #17
0
 public static bool IsSystemArgIterator(TypeSystemContext context, TypeDesc type)
 {
     return(IsCoreNamedType(context, type, "System", "ArgIterator"));
 }
Example #18
0
        /// <summary>
        /// Attempts to resolve constrained call to <paramref name="interfaceMethod"/> into a concrete non-unboxing
        /// method on <paramref name="constrainedType"/>.
        /// The ability to resolve constraint methods is affected by the degree of code sharing we are performing
        /// for generic code.
        /// </summary>
        /// <returns>The resolved method or null if the constraint couldn't be resolved.</returns>
        public static MethodDesc TryResolveConstraintMethodApprox(this TypeDesc constrainedType, TypeDesc interfaceType, MethodDesc interfaceMethod, out bool forceRuntimeLookup)
        {
            forceRuntimeLookup = false;

            bool isStaticVirtualMethod = interfaceMethod.Signature.IsStatic;

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

            // Interface method may or may not be fully canonicalized here.
            // It would be canonical on the CoreCLR side so canonicalize here to keep the algorithms similar.
            Instantiation methodInstantiation = interfaceMethod.Instantiation;

            interfaceMethod = interfaceMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);

            // 1. Find the (possibly generic) method that would implement the
            // constraint if we were making a call on a boxed value type.

            TypeDesc          canonType = constrainedType.ConvertToCanonForm(CanonicalFormKind.Specific);
            TypeSystemContext context   = constrainedType.Context;

            MethodDesc genInterfaceMethod = interfaceMethod.GetMethodDefinition();
            MethodDesc method             = null;

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

                // Enumerate all potential interface instantiations
                int potentialMatchingInterfaces = 0;
                foreach (DefType potentialInterfaceType in canonType.RuntimeInterfaces)
                {
                    if (potentialInterfaceType.ConvertToCanonForm(CanonicalFormKind.Specific) ==
                        interfaceType.ConvertToCanonForm(CanonicalFormKind.Specific))
                    {
                        potentialMatchingInterfaces++;
                        MethodDesc potentialInterfaceMethod = genInterfaceMethod;
                        if (potentialInterfaceMethod.OwningType != potentialInterfaceType)
                        {
                            potentialInterfaceMethod = context.GetMethodForInstantiatedType(
                                potentialInterfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)potentialInterfaceType);
                        }

                        if (isStaticVirtualMethod)
                        {
                            method = canonType.ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(potentialInterfaceMethod);
                        }
                        else
                        {
                            method = canonType.ResolveInterfaceMethodToVirtualMethodOnType(potentialInterfaceMethod);
                        }

                        // See code:#TryResolveConstraintMethodApprox_DoNotReturnParentMethod
                        if (!isStaticVirtualMethod && method != null && !method.OwningType.IsValueType)
                        {
                            // We explicitly wouldn't want to abort if we found a default implementation.
                            // The above resolution doesn't consider the default methods.
                            Debug.Assert(!method.OwningType.IsInterface);
                            return(null);
                        }
                    }
                }

                Debug.Assert(potentialMatchingInterfaces != 0);

                if (potentialMatchingInterfaces > 1)
                {
                    // We have more potentially matching interfaces
                    Debug.Assert(interfaceType.HasInstantiation);

                    bool isExactMethodResolved = false;

                    if (!interfaceType.IsCanonicalSubtype(CanonicalFormKind.Any) &&
                        !interfaceType.IsGenericDefinition &&
                        !constrainedType.IsCanonicalSubtype(CanonicalFormKind.Any) &&
                        !constrainedType.IsGenericDefinition)
                    {
                        // We have exact interface and type instantiations (no generic variables and __Canon used
                        // anywhere)
                        if (constrainedType.CanCastTo(interfaceType))
                        {
                            // We can resolve to exact method
                            MethodDesc exactInterfaceMethod = context.GetMethodForInstantiatedType(
                                genInterfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceType);
                            if (isStaticVirtualMethod)
                            {
                                method = constrainedType.ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(exactInterfaceMethod);
                            }
                            else
                            {
                                method = constrainedType.ResolveVariantInterfaceMethodToVirtualMethodOnType(exactInterfaceMethod);
                            }
                            isExactMethodResolved = method != null;
                        }
                    }

                    if (!isExactMethodResolved)
                    {
                        // We couldn't resolve the interface statically
                        // Notify the caller that it should use runtime lookup
                        // Note that we can leave pMD incorrect, because we will use runtime lookup
                        forceRuntimeLookup = true;
                    }
                }
                else
                {
                    // If we can resolve the interface exactly then do so (e.g. when doing the exact
                    // lookup at runtime, or when not sharing generic code).
                    if (constrainedType.CanCastTo(interfaceType))
                    {
                        MethodDesc exactInterfaceMethod = genInterfaceMethod;
                        if (genInterfaceMethod.OwningType != interfaceType)
                        {
                            exactInterfaceMethod = context.GetMethodForInstantiatedType(
                                genInterfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceType);
                        }
                        if (isStaticVirtualMethod)
                        {
                            method = constrainedType.ResolveVariantInterfaceMethodToStaticVirtualMethodOnType(exactInterfaceMethod);
                        }
                        else
                        {
                            method = constrainedType.ResolveVariantInterfaceMethodToVirtualMethodOnType(exactInterfaceMethod);
                        }
                    }
                }
            }
            else if (genInterfaceMethod.IsVirtual)
            {
                MethodDesc targetMethod = interfaceType.FindMethodOnTypeWithMatchingTypicalMethod(genInterfaceMethod);
                method = constrainedType.FindVirtualFunctionTargetMethodOnObjectType(targetMethod);
            }
            else
            {
                // The method will be null if calling a non-virtual instance
                // methods on System.Object, i.e. when these are used as a constraint.
                method = null;
            }

            // Default implementation logic, which only kicks in for default implementations when looking up on an exact interface target
            if (isStaticVirtualMethod && method == null && !genInterfaceMethod.IsAbstract && !constrainedType.IsCanonicalSubtype(CanonicalFormKind.Any))
            {
                MethodDesc exactInterfaceMethod = genInterfaceMethod;
                if (genInterfaceMethod.OwningType != interfaceType)
                {
                    exactInterfaceMethod = context.GetMethodForInstantiatedType(
                        genInterfaceMethod.GetTypicalMethodDefinition(), (InstantiatedType)interfaceType);
                }
                method = exactInterfaceMethod;
            }

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

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

            // We've resolved the method, ignoring its generic method arguments
            // If the method is a generic method then go and get the instantiated descriptor
            if (methodInstantiation.Length != 0)
            {
                method = method.MakeInstantiatedMethod(methodInstantiation);
            }

            Debug.Assert(method != null);

            return(method);
        }
 public LibraryInitializers(TypeSystemContext context, IEnumerable <ModuleDesc> librariesWithInitalizers)
 {
     _context = context;
     _librariesWithInitializers = new List <ModuleDesc>(librariesWithInitalizers);
 }
 public static bool HasLazyStaticConstructor(this TypeSystemContext context, TypeDesc type)
 {
     return(type.HasStaticConstructor);
 }
 public MrtProcessedImportAddressTableNode(string exportTableToImportSymbol, TypeSystemContext context) : base("_ImportTable_" + exportTableToImportSymbol, "_ImportTable_end_" + exportTableToImportSymbol)
 {
     ExportTableToImportSymbol = exportTableToImportSymbol;
     _pointerSize = context.Target.PointerSize;
 }
        /// <summary>
        /// Parse an MIBC file for the methods that are interesting.
        /// The version bubble must be specified and will describe the restrict the set of methods parsed to those relevant to the compilation
        /// The onlyDefinedInAssembly parameter is used to restrict the set of types parsed to include only those which are defined in a specific module. Specify null to allow definitions from all modules.
        /// This limited parsing is not necessarily an exact set of prevention, so detailed algorithms that work at the individual method level are still necessary, but this allows avoiding excessive parsing.
        ///
        /// The format of the Mibc file is that of a .NET dll, with a global method named "AssemblyDictionary". Inside of that file are a series of references that are broken up by which assemblies define the individual methods.
        /// These references are encoded as IL code that represents the details.
        /// The format of these IL instruction is as follows.
        ///
        /// ldstr mibcGroupName
        /// ldtoken mibcGroupMethod
        /// pop
        /// {Repeat the above pattern N times, once per Mibc group}
        ///
        /// See comment above ReadMIbcGroup for details of the group format
        ///
        /// The mibcGroupName is in the following format "Assembly_{definingAssemblyName};{OtherAssemblyName};{OtherAssemblyName};...; (OtherAssemblyName is ; delimited)
        ///
        /// </summary>
        /// <returns></returns>
        public static ProfileData ParseMIbcFile(TypeSystemContext tsc, PEReader peReader, HashSet <string> assemblyNamesInVersionBubble, string onlyDefinedInAssembly)
        {
            var mibcModule = EcmaModule.Create(tsc, peReader, null, null, new CustomCanonResolver(tsc));

            var assemblyDictionary = (EcmaMethod)mibcModule.GetGlobalModuleType().GetMethod("AssemblyDictionary", null);
            IEnumerable <MethodProfileData> loadedMethodProfileData = Enumerable.Empty <MethodProfileData>();

            EcmaMethodIL ilBody   = EcmaMethodIL.Create(assemblyDictionary);
            ILReader     ilReader = new ILReader(ilBody.GetILBytes());

            string mibcGroupName = "";

            while (ilReader.HasNext)
            {
                ILOpcode opcode = ilReader.ReadILOpcode();
                switch (opcode)
                {
                case ILOpcode.ldstr:
                    int userStringToken = ilReader.ReadILToken();
                    Debug.Assert(mibcGroupName == "");
                    if (mibcGroupName == "")
                    {
                        mibcGroupName = (string)ilBody.GetObject(userStringToken);
                    }
                    break;

                case ILOpcode.ldtoken:
                    int token = ilReader.ReadILToken();

                    if (String.IsNullOrEmpty(mibcGroupName))
                    {
                        break;
                    }

                    string[] assembliesByName = mibcGroupName.Split(';');

                    bool hasMatchingDefinition = (onlyDefinedInAssembly == null) || assembliesByName[0].Equals(onlyDefinedInAssembly);

                    if (!hasMatchingDefinition)
                    {
                        break;
                    }

                    if (assemblyNamesInVersionBubble != null)
                    {
                        bool areAllEntriesInVersionBubble = true;
                        foreach (string s in assembliesByName)
                        {
                            if (string.IsNullOrEmpty(s))
                            {
                                continue;
                            }

                            if (!assemblyNamesInVersionBubble.Contains(s))
                            {
                                areAllEntriesInVersionBubble = false;
                                break;
                            }
                        }

                        if (!areAllEntriesInVersionBubble)
                        {
                            break;
                        }
                    }

                    loadedMethodProfileData = loadedMethodProfileData.Concat(ReadMIbcGroup(tsc, (EcmaMethod)ilBody.GetObject(token)));
                    break;

                case ILOpcode.pop:
                    mibcGroupName = "";
                    break;

                default:
                    ilReader.Skip(opcode);
                    break;
                }
            }

            return(new IBCProfileData(false, loadedMethodProfileData));
        }
Example #23
0
        /// <summary>
        /// Retrieves method whose runtime handle is suitable for use with GVMLookupForSlot.
        /// </summary>
        public MethodDesc GetTargetOfGenericVirtualMethodCall(MethodDesc calledMethod)
        {
            // Should be a generic virtual method
            Debug.Assert(calledMethod.HasInstantiation && calledMethod.IsVirtual);

            // Needs to be either a concrete method, or a runtime determined form.
            Debug.Assert(!calledMethod.IsCanonicalMethod(CanonicalFormKind.Specific));

            MethodDesc targetMethod           = calledMethod.GetCanonMethodTarget(CanonicalFormKind.Specific);
            MethodDesc targetMethodDefinition = targetMethod.GetMethodDefinition();

            MethodDesc slotNormalizedMethodDefinition = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(targetMethodDefinition);

            // If the method defines the slot, we can use that.
            if (slotNormalizedMethodDefinition == targetMethodDefinition)
            {
                return(calledMethod);
            }

            // Normalize to the slot defining method
            MethodDesc slotNormalizedMethod = TypeSystemContext.GetInstantiatedMethod(
                slotNormalizedMethodDefinition,
                targetMethod.Instantiation);

            // Since the slot normalization logic modified what method we're looking at, we need to compute the new target of lookup.
            //
            // If we could use virtual method resolution logic with runtime determined methods, we wouldn't need what we're going
            // to do below.
            MethodDesc runtimeDeterminedSlotNormalizedMethod;

            if (!slotNormalizedMethod.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any))
            {
                // If the owning type is not generic, we can use it as-is, potentially only replacing the runtime-determined
                // method instantiation part.
                runtimeDeterminedSlotNormalizedMethod = slotNormalizedMethod.GetMethodDefinition();
            }
            else
            {
                // If we need a runtime lookup but a normalization to the slot defining method happened above, we need to compute
                // the runtime lookup in terms of the base type that introduced the slot.
                //
                // To do that, we walk the base hierarchy of the runtime determined thing, looking for a type definition that matches
                // the slot-normalized virtual method. We then find the method on that type.
                TypeDesc runtimeDeterminedOwningType = calledMethod.OwningType;

                Debug.Assert(!runtimeDeterminedOwningType.IsInterface);

                while (!slotNormalizedMethod.OwningType.HasSameTypeDefinition(runtimeDeterminedOwningType))
                {
                    TypeDesc runtimeDeterminedBaseTypeDefinition = runtimeDeterminedOwningType.GetTypeDefinition().BaseType;
                    if (runtimeDeterminedBaseTypeDefinition.HasInstantiation)
                    {
                        runtimeDeterminedOwningType = runtimeDeterminedBaseTypeDefinition.InstantiateSignature(runtimeDeterminedOwningType.Instantiation, default);
                    }
                    else
                    {
                        runtimeDeterminedOwningType = runtimeDeterminedBaseTypeDefinition;
                    }
                }

                // Now get the method on the newly found type
                Debug.Assert(runtimeDeterminedOwningType.HasInstantiation);
                runtimeDeterminedSlotNormalizedMethod = TypeSystemContext.GetMethodForInstantiatedType(
                    slotNormalizedMethod.GetTypicalMethodDefinition(),
                    (InstantiatedType)runtimeDeterminedOwningType);
            }

            return(TypeSystemContext.GetInstantiatedMethod(runtimeDeterminedSlotNormalizedMethod, calledMethod.Instantiation));
        }
 public CanonModule(TypeSystemContext wrappedContext) : base(wrappedContext, null)
 {
 }
Example #25
0
 public NodeFactory(TypeSystemContext typeSystemContext)
 {
     _targetDetails     = typeSystemContext.Target;
     _typeSystemContext = typeSystemContext;
     CreateNodeCaches();
 }
Example #26
0
        private void CreateNodeCaches()
        {
            _typeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) =>
            {
                if (_compilationModuleGroup.ContainsType(type))
                {
                    if (type.IsGenericDefinition)
                    {
                        return(new GenericDefinitionEETypeNode(this, type));
                    }
                    else
                    {
                        return(new EETypeNode(this, type));
                    }
                }
                else
                {
                    return(new ExternEETypeSymbolNode(this, type));
                }
            });

            _constructedTypeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) =>
            {
                if (_compilationModuleGroup.ContainsType(type))
                {
                    return(new ConstructedEETypeNode(this, type));
                }
                else
                {
                    return(new ExternEETypeSymbolNode(this, type));
                }
            });

            _clonedTypeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) =>
            {
                // Only types that reside in other binaries should be cloned
                Debug.Assert(_compilationModuleGroup.ShouldReferenceThroughImportTable(type));
                return(new ClonedConstructedEETypeNode(this, type));
            });

            _nonGCStatics = new NodeCache <MetadataType, NonGCStaticsNode>((MetadataType type) =>
            {
                return(new NonGCStaticsNode(type, this));
            });

            _GCStatics = new NodeCache <MetadataType, GCStaticsNode>((MetadataType type) =>
            {
                return(new GCStaticsNode(type));
            });

            _GCStaticIndirectionNodes = new NodeCache <MetadataType, EmbeddedObjectNode>((MetadataType type) =>
            {
                ISymbolNode gcStaticsNode = TypeGCStaticsSymbol(type);
                Debug.Assert(gcStaticsNode is GCStaticsNode);
                return(GCStaticsRegion.NewNode((GCStaticsNode)gcStaticsNode));
            });

            _threadStatics = new NodeCache <MetadataType, ThreadStaticsNode>((MetadataType type) =>
            {
                return(new ThreadStaticsNode(type, this));
            });

            _GCStaticEETypes = new NodeCache <GCPointerMap, GCStaticEETypeNode>((GCPointerMap gcMap) =>
            {
                return(new GCStaticEETypeNode(Target, gcMap));
            });

            _readOnlyDataBlobs = new NodeCache <Tuple <Utf8String, byte[], int>, BlobNode>((Tuple <Utf8String, byte[], int> key) =>
            {
                return(new BlobNode(key.Item1, ObjectNodeSection.ReadOnlyDataSection, key.Item2, key.Item3));
            }, new BlobTupleEqualityComparer());

            _externSymbols = new NodeCache <string, ExternSymbolNode>((string name) =>
            {
                return(new ExternSymbolNode(name));
            });

            _pInvokeModuleFixups = new NodeCache <string, PInvokeModuleFixupNode>((string name) =>
            {
                return(new PInvokeModuleFixupNode(name));
            });

            _pInvokeMethodFixups = new NodeCache <Tuple <string, string>, PInvokeMethodFixupNode>((Tuple <string, string> key) =>
            {
                return(new PInvokeMethodFixupNode(key.Item1, key.Item2));
            });

            _methodEntrypoints = new NodeCache <MethodDesc, IMethodNode>(CreateMethodEntrypointNode);

            _unboxingStubs = new NodeCache <MethodDesc, IMethodNode>(CreateUnboxingStubNode);

            _fatFunctionPointers = new NodeCache <MethodDesc, FatFunctionPointerNode>(method =>
            {
                return(new FatFunctionPointerNode(method));
            });

            _shadowConcreteMethods = new NodeCache <MethodDesc, IMethodNode>(method =>
            {
                return(new ShadowConcreteMethodNode <MethodCodeNode>(method,
                                                                     (MethodCodeNode)MethodEntrypoint(method.GetCanonMethodTarget(CanonicalFormKind.Specific))));
            });

            _runtimeDeterminedMethods = new NodeCache <MethodDesc, IMethodNode>(method =>
            {
                return(new RuntimeDeterminedMethodNode(method,
                                                       MethodEntrypoint(method.GetCanonMethodTarget(CanonicalFormKind.Specific))));
            });

            _virtMethods = new NodeCache <MethodDesc, VirtualMethodUseNode>((MethodDesc method) =>
            {
                return(new VirtualMethodUseNode(method));
            });

            _readyToRunHelpers = new NodeCache <Tuple <ReadyToRunHelperId, Object>, ISymbolNode>(CreateReadyToRunHelperNode);

            _genericReadyToRunHelpersFromDict = new NodeCache <Tuple <ReadyToRunHelperId, object, TypeSystemEntity>, ISymbolNode>(data =>
            {
                return(new ReadyToRunGenericLookupFromDictionaryNode(this, data.Item1, data.Item2, data.Item3));
            });

            _genericReadyToRunHelpersFromType = new NodeCache <Tuple <ReadyToRunHelperId, object, TypeSystemEntity>, ISymbolNode>(data =>
            {
                return(new ReadyToRunGenericLookupFromTypeNode(this, data.Item1, data.Item2, data.Item3));
            });

            _indirectionNodes = new NodeCache <ISymbolNode, IndirectionNode>(symbol =>
            {
                return(new IndirectionNode(symbol));
            });

            _frozenStringNodes = new NodeCache <string, FrozenStringNode>((string data) =>
            {
                return(new FrozenStringNode(data, Target));
            });

            _interfaceDispatchCells = new NodeCache <MethodDesc, InterfaceDispatchCellNode>((MethodDesc method) =>
            {
                return(new InterfaceDispatchCellNode(method));
            });

            _interfaceDispatchMaps = new NodeCache <TypeDesc, InterfaceDispatchMapNode>((TypeDesc type) =>
            {
                return(new InterfaceDispatchMapNode(type));
            });

            _interfaceDispatchMapIndirectionNodes = new NodeCache <TypeDesc, EmbeddedObjectNode>((TypeDesc type) =>
            {
                var dispatchMap = InterfaceDispatchMap(type);
                return(DispatchMapTable.NewNodeWithSymbol(dispatchMap, (indirectionNode) =>
                {
                    dispatchMap.SetDispatchMapIndex(this, DispatchMapTable.IndexOfEmbeddedObject(indirectionNode));
                }));
            });

            _genericCompositions = new NodeCache <GenericCompositionDetails, GenericCompositionNode>((GenericCompositionDetails details) =>
            {
                return(new GenericCompositionNode(details));
            });

            _eagerCctorIndirectionNodes = new NodeCache <MethodDesc, EmbeddedObjectNode>((MethodDesc method) =>
            {
                Debug.Assert(method.IsStaticConstructor);
                Debug.Assert(TypeSystemContext.HasEagerStaticConstructor((MetadataType)method.OwningType));
                return(EagerCctorTable.NewNode(MethodEntrypoint(method)));
            });

            _vTableNodes = new NodeCache <TypeDesc, VTableSliceNode>((TypeDesc type ) =>
            {
                if (CompilationModuleGroup.ShouldProduceFullType(type))
                {
                    return(new EagerlyBuiltVTableSliceNode(type));
                }
                else
                {
                    return(new LazilyBuiltVTableSliceNode(type));
                }
            });

            _methodGenericDictionaries = new NodeCache <MethodDesc, GenericDictionaryNode>(method =>
            {
                return(new MethodGenericDictionaryNode(method));
            });

            _typeGenericDictionaries = new NodeCache <TypeDesc, GenericDictionaryNode>(type =>
            {
                return(new TypeGenericDictionaryNode(type));
            });

            _genericDictionaryLayouts = new NodeCache <TypeSystemEntity, DictionaryLayoutNode>(methodOrType =>
            {
                return(new DictionaryLayoutNode(methodOrType));
            });

            _stringAllocators = new NodeCache <MethodDesc, IMethodNode>(constructor =>
            {
                return(new StringAllocatorMethodNode(constructor));
            });
        }
        private static bool ResolveType(string name, ModuleDesc callingModule, out TypeDesc type, out ModuleDesc referenceModule)
        {
            // This can do enough resolution to resolve "Foo" or "Foo, Assembly, PublicKeyToken=...".
            // The reflection resolution rules are complicated. This is only needed for a heuristic,
            // not for correctness, so this shortcut is okay.

            type            = null;
            referenceModule = null;

            int i = 0;

            // Consume type name part
            StringBuilder typeName      = new StringBuilder();
            StringBuilder typeNamespace = new StringBuilder();

            while (i < name.Length && (char.IsLetterOrDigit(name[i]) || name[i] == '.' || name[i] == '`'))
            {
                if (name[i] == '.')
                {
                    if (typeNamespace.Length > 0)
                    {
                        typeNamespace.Append('.');
                    }
                    typeNamespace.Append(typeName);
                    typeName.Clear();
                }
                else
                {
                    typeName.Append(name[i]);
                }
                i++;
            }

            // Consume any comma or white space
            while (i < name.Length && (name[i] == ' ' || name[i] == ','))
            {
                i++;
            }

            // Consume assembly name
            StringBuilder assemblyName = new StringBuilder();

            while (i < name.Length && (char.IsLetterOrDigit(name[i]) || name[i] == '.'))
            {
                assemblyName.Append(name[i]);
                i++;
            }

            TypeSystemContext context = callingModule.Context;

            // If the name was assembly-qualified, resolve the assembly
            // If it wasn't qualified, we resolve in the calling assembly

            referenceModule = callingModule;
            if (assemblyName.Length > 0)
            {
                referenceModule = context.ResolveAssembly(new AssemblyName(assemblyName.ToString()), false);
                if (referenceModule == null)
                {
                    return(false);
                }
            }

            // Resolve type in the assembly
            type = referenceModule.GetType(typeNamespace.ToString(), typeName.ToString(), false);

            // If it didn't resolve and wasn't assembly-qualified, we also try core library
            if (type == null && assemblyName.Length == 0)
            {
                referenceModule = context.SystemModule;
                type            = referenceModule.GetType(typeNamespace.ToString(), typeName.ToString(), false);
            }

            return(type != null);
        }
Example #28
0
        /// <summary>
        /// Returns JIT helper entrypoint. JIT helpers can be either implemented by entrypoint with given mangled name or
        /// by a method in class library.
        /// </summary>
        public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id, out string mangledName, out MethodDesc methodDesc)
        {
            mangledName = null;
            methodDesc  = null;

            switch (id)
            {
            case ReadyToRunHelper.Throw:
                mangledName = "RhpThrowEx";
                break;

            case ReadyToRunHelper.Rethrow:
                mangledName = "RhpRethrow";
                break;

            case ReadyToRunHelper.Overflow:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowOverflowException");
                break;

            case ReadyToRunHelper.RngChkFail:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowIndexOutOfRangeException");
                break;

            case ReadyToRunHelper.FailFast:
                mangledName = "__fail_fast";     // TODO: Report stack buffer overrun
                break;

            case ReadyToRunHelper.ThrowNullRef:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowNullReferenceException");
                break;

            case ReadyToRunHelper.ThrowDivZero:
                methodDesc = context.GetHelperEntryPoint("ThrowHelpers", "ThrowDivideByZeroException");
                break;

            case ReadyToRunHelper.DebugBreak:
                mangledName = "RhDebugBreak";
                break;

            case ReadyToRunHelper.WriteBarrier:
                mangledName = "RhpAssignRef";
                break;

            case ReadyToRunHelper.CheckedWriteBarrier:
                mangledName = "RhpCheckedAssignRef";
                break;

            case ReadyToRunHelper.ByRefWriteBarrier:
                mangledName = "RhpByRefAssignRef";
                break;

            case ReadyToRunHelper.Box:
            case ReadyToRunHelper.Box_Nullable:
                mangledName = "RhBox";
                break;

            case ReadyToRunHelper.Unbox:
                mangledName = "RhUnbox2";
                break;

            case ReadyToRunHelper.Unbox_Nullable:
                mangledName = "RhUnboxNullable";
                break;

            case ReadyToRunHelper.NewMultiDimArr_NonVarArg:
                methodDesc = context.GetHelperEntryPoint("ArrayHelpers", "NewObjArray");
                break;

            case ReadyToRunHelper.NewArray:
                mangledName = "RhNewArray";
                break;

            case ReadyToRunHelper.NewObject:
                mangledName = "RhNewObject";
                break;

            case ReadyToRunHelper.Stelem_Ref:
                mangledName = "RhpStelemRef";
                break;

            case ReadyToRunHelper.Ldelema_Ref:
                mangledName = "RhpLdelemaRef";
                break;

            case ReadyToRunHelper.MemCpy:
                mangledName = "memcpy";     // TODO: Null reference handling
                break;

            case ReadyToRunHelper.MemSet:
                mangledName = "memset";     // TODO: Null reference handling
                break;

            case ReadyToRunHelper.GetRuntimeTypeHandle:
                methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeTypeHandle");
                break;

            case ReadyToRunHelper.GetRuntimeMethodHandle:
                methodDesc = context.GetHelperEntryPoint("LdTokenHelpers", "GetRuntimeMethodHandle");
                break;

            case ReadyToRunHelper.GetRuntimeFieldHandle:     // TODO: Reflection
                mangledName = "__fail_fast";
                break;

            case ReadyToRunHelper.Lng2Dbl:
                mangledName = "RhpLng2Dbl";
                break;

            case ReadyToRunHelper.ULng2Dbl:
                mangledName = "RhpULng2Dbl";
                break;

            case ReadyToRunHelper.Dbl2Lng:
                mangledName = "RhpDbl2Lng";
                break;

            case ReadyToRunHelper.Dbl2ULng:
                mangledName = "RhpDbl2ULng";
                break;

            case ReadyToRunHelper.Dbl2IntOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2IntOvf");
                break;

            case ReadyToRunHelper.Dbl2UIntOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2UIntOvf");
                break;

            case ReadyToRunHelper.Dbl2LngOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2LngOvf");
                break;

            case ReadyToRunHelper.Dbl2ULngOvf:
                methodDesc = context.GetHelperEntryPoint("MathHelpers", "Dbl2ULngOvf");
                break;

            case ReadyToRunHelper.DblRem:
                mangledName = "RhpDblRem";
                break;

            case ReadyToRunHelper.FltRem:
                mangledName = "RhpFltRem";
                break;

            case ReadyToRunHelper.PInvokeBegin:
                mangledName = "RhpPInvoke";
                break;

            case ReadyToRunHelper.PInvokeEnd:
                mangledName = "RhpPInvokeReturn";
                break;

            case ReadyToRunHelper.ReversePInvokeEnter:
                mangledName = "RhpReversePInvoke2";
                break;

            case ReadyToRunHelper.ReversePInvokeExit:
                mangledName = "RhpReversePInvokeReturn2";
                break;

            case ReadyToRunHelper.CheckCastAny:
                mangledName = "RhTypeCast_CheckCast2";
                break;

            case ReadyToRunHelper.CheckInstanceAny:
                mangledName = "RhTypeCast_IsInstanceOf2";
                break;

            case ReadyToRunHelper.MonitorEnter:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorEnter");
                break;

            case ReadyToRunHelper.MonitorExit:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorExit");
                break;

            case ReadyToRunHelper.MonitorEnterStatic:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorEnterStatic");
                break;

            case ReadyToRunHelper.MonitorExitStatic:
                methodDesc = context.GetHelperEntryPoint("SynchronizedMethodHelpers", "MonitorExitStatic");
                break;

            default:
                throw new NotImplementedException(id.ToString());
            }
        }
        private bool ResolveGenericVirtualMethodTarget(RuntimeTypeHandle targetTypeHandle, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeHandle[] genericArguments, MethodNameAndSignature callingMethodNameAndSignature, out IntPtr methodPointer, out IntPtr dictionaryPointer)
        {
            if (IsPregeneratedOrTemplateRuntimeTypeHandle(targetTypeHandle))
            {
                // If the target type isn't dynamic, or at least is template type generated, the static lookup logic is what we want.
                return(ResolveGenericVirtualMethodTarget_Static(targetTypeHandle, declaringTypeHandle, genericArguments, callingMethodNameAndSignature, out methodPointer, out dictionaryPointer));
            }
            else
            {
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
                methodPointer     = IntPtr.Zero;
                dictionaryPointer = IntPtr.Zero;

                TypeSystemContext context    = TypeSystemContextFactory.Create();
                DefType           targetType = (DefType)context.ResolveRuntimeTypeHandle(targetTypeHandle);

                // Method being called...
                MethodDesc targetVirtualMethod = ResolveTypeHandleAndMethodNameAndSigToVirtualMethodDesc(context, declaringTypeHandle, callingMethodNameAndSignature);

                if (targetVirtualMethod == null)
                {
                    // If we can't find the method in the type system, it must only be present in the static environment. Search there instead.
                    TypeSystemContextFactory.Recycle(context);
                    return(ResolveGenericVirtualMethodTarget_Static(targetTypeHandle, declaringTypeHandle, genericArguments, callingMethodNameAndSignature, out methodPointer, out dictionaryPointer));
                }

                MethodDesc dispatchMethod = targetType.FindVirtualFunctionTargetMethodOnObjectType(targetVirtualMethod);

                if (dispatchMethod == null)
                {
                    return(false);
                }

                Instantiation targetMethodInstantiation  = context.ResolveRuntimeTypeHandles(genericArguments);
                MethodDesc    instantiatedDispatchMethod = dispatchMethod.Context.ResolveGenericMethodInstantiation(dispatchMethod.OwningType.IsValueType /* get the unboxing stub */,
                                                                                                                    dispatchMethod.OwningType.GetClosestDefType(),
                                                                                                                    dispatchMethod.NameAndSignature,
                                                                                                                    targetMethodInstantiation, IntPtr.Zero, false);

                GenericDictionaryCell cell = GenericDictionaryCell.CreateMethodCell(instantiatedDispatchMethod, false);
                using (LockHolder.Hold(_typeLoaderLock))
                {
                    // Now that we hold the lock, we may find that existing types can now find
                    // their associated RuntimeTypeHandle. Flush the type builder states as a way
                    // to force the reresolution of RuntimeTypeHandles which couldn't be found before.
                    context.FlushTypeBuilderStates();

                    TypeBuilder.ResolveSingleCell(cell, out methodPointer);
                }

                TypeSystemContextFactory.Recycle(context);

                return(true);
#else
                methodPointer     = IntPtr.Zero;
                dictionaryPointer = IntPtr.Zero;
                Environment.FailFast("GVM Resolution for non template or pregenerated type");
                return(false);
#endif
            }
        }
Example #30
0
        //
        // Lazily parse the method signature, and construct the call converter data
        //
        private void EnsureCallConversionInfoLoaded()
        {
            if (_signatureParsed)
            {
                return;
            }

            lock (this)
            {
                // Check if race was won by another thread and the signature got parsed
                if (_signatureParsed)
                {
                    return;
                }

                TypeSystemContext context = TypeSystemContextFactory.Create();
                {
                    Instantiation typeInstantiation   = Instantiation.Empty;
                    Instantiation methodInstantiation = Instantiation.Empty;

                    if (_typeArgs != null && _typeArgs.Length > 0)
                    {
                        typeInstantiation = context.ResolveRuntimeTypeHandles(_typeArgs);
                    }
                    if (_methodArgs != null && _methodArgs.Length > 0)
                    {
                        methodInstantiation = context.ResolveRuntimeTypeHandles(_methodArgs);
                    }

                    bool       hasThis;
                    TypeDesc[] parameters;
                    bool[]     paramsByRefForced;
                    if (!TypeLoaderEnvironment.Instance.GetCallingConverterDataFromMethodSignature(context, _methodSignature, typeInstantiation, methodInstantiation, out hasThis, out parameters, out paramsByRefForced))
                    {
                        Debug.Assert(false);
                        Environment.FailFast("Failed to get type handles for parameters in method signature");
                    }
                    Debug.Assert(parameters != null && parameters.Length >= 1);

                    bool[] byRefParameters = new bool[parameters.Length];
                    RuntimeTypeHandle[] parameterHandles = new RuntimeTypeHandle[parameters.Length];

                    for (int j = 0; j < parameters.Length; j++)
                    {
                        ByRefType parameterAsByRefType = parameters[j] as ByRefType;
                        if (parameterAsByRefType != null)
                        {
                            parameterAsByRefType.ParameterType.RetrieveRuntimeTypeHandleIfPossible();
                            parameterHandles[j] = parameterAsByRefType.ParameterType.RuntimeTypeHandle;
                            byRefParameters[j]  = true;
                        }
                        else
                        {
                            parameters[j].RetrieveRuntimeTypeHandleIfPossible();
                            parameterHandles[j] = parameters[j].RuntimeTypeHandle;
                            byRefParameters[j]  = false;
                        }

                        Debug.Assert(!parameterHandles[j].IsNull());
                    }

                    // Build thunk data
                    TypeHandle   thReturnType = new TypeHandle(CallConverterThunk.GetByRefIndicatorAtIndex(0, byRefParameters), parameterHandles[0]);
                    TypeHandle[] thParameters = null;
                    if (parameters.Length > 1)
                    {
                        thParameters = new TypeHandle[parameters.Length - 1];
                        for (int i = 1; i < parameters.Length; i++)
                        {
                            thParameters[i - 1] = new TypeHandle(CallConverterThunk.GetByRefIndicatorAtIndex(i, byRefParameters), parameterHandles[i]);
                        }
                    }

                    _argIteratorData = new ArgIteratorData(hasThis, false, thParameters, thReturnType);

                    // StandardToStandard thunks don't actually need any parameters to change their ABI
                    // so don't force any params to be adjusted
                    if (!StandardToStandardThunk)
                    {
                        _paramsByRefForced = paramsByRefForced;
                    }
                }
                TypeSystemContextFactory.Recycle(context);

                _signatureParsed = true;
            }
        }
Example #31
0
 public bool HasLazyStaticConstructor(TypeDesc type)
 {
     return(TypeSystemContext.HasLazyStaticConstructor(type));
 }
Example #32
0
 public ModuleDesc(TypeSystemContext context)
 {
     Context = context;
 }
Example #33
0
 protected override void PrepareRuntimeSpecificStaticFieldLayout(TypeSystemContext context, ref ComputedStaticFieldLayout layout)
 {
     // GC statics start with a pointer to the "MethodTable" that signals the size and GCDesc to the GC
     layout.GcStatics.Size       = context.Target.LayoutPointerSize;
     layout.ThreadGcStatics.Size = context.Target.LayoutPointerSize;
 }
Example #34
0
        private void CreateNodeCaches()
        {
            _typeSymbols = new NodeCache <TypeDesc, IEETypeNode>(CreateNecessaryTypeNode);

            _constructedTypeSymbols = new NodeCache <TypeDesc, IEETypeNode>(CreateConstructedTypeNode);

            _clonedTypeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) =>
            {
                // Only types that reside in other binaries should be cloned
                Debug.Assert(_compilationModuleGroup.ShouldReferenceThroughImportTable(type));
                return(new ClonedConstructedEETypeNode(this, type));
            });

            _importedTypeSymbols = new NodeCache <TypeDesc, IEETypeNode>((TypeDesc type) =>
            {
                Debug.Assert(_compilationModuleGroup.ShouldReferenceThroughImportTable(type));
                return(_importedNodeProvider.ImportedEETypeNode(this, type));
            });

            _nonGCStatics = new NodeCache <MetadataType, ISortableSymbolNode>((MetadataType type) =>
            {
                if (_compilationModuleGroup.ContainsType(type) && !_compilationModuleGroup.ShouldReferenceThroughImportTable(type))
                {
                    return(new NonGCStaticsNode(type, this));
                }
                else
                {
                    return(_importedNodeProvider.ImportedNonGCStaticNode(this, type));
                }
            });

            _GCStatics = new NodeCache <MetadataType, ISortableSymbolNode>((MetadataType type) =>
            {
                if (_compilationModuleGroup.ContainsType(type) && !_compilationModuleGroup.ShouldReferenceThroughImportTable(type))
                {
                    return(new GCStaticsNode(type));
                }
                else
                {
                    return(_importedNodeProvider.ImportedGCStaticNode(this, type));
                }
            });

            _GCStaticsPreInitDataNodes = new NodeCache <MetadataType, GCStaticsPreInitDataNode>((MetadataType type) =>
            {
                ISymbolNode gcStaticsNode = TypeGCStaticsSymbol(type);
                Debug.Assert(gcStaticsNode is GCStaticsNode);
                return(((GCStaticsNode)gcStaticsNode).NewPreInitDataNode());
            });

            _GCStaticIndirectionNodes = new NodeCache <MetadataType, EmbeddedObjectNode>((MetadataType type) =>
            {
                ISymbolNode gcStaticsNode = TypeGCStaticsSymbol(type);
                Debug.Assert(gcStaticsNode is GCStaticsNode);
                return(GCStaticsRegion.NewNode((GCStaticsNode)gcStaticsNode));
            });

            _threadStatics = new NodeCache <MetadataType, ISymbolDefinitionNode>(CreateThreadStaticsNode);

            _typeThreadStaticIndices = new NodeCache <MetadataType, TypeThreadStaticIndexNode>(type =>
            {
                return(new TypeThreadStaticIndexNode(type));
            });

            _GCStaticEETypes = new NodeCache <GCPointerMap, GCStaticEETypeNode>((GCPointerMap gcMap) =>
            {
                return(new GCStaticEETypeNode(Target, gcMap));
            });

            _readOnlyDataBlobs = new NodeCache <ReadOnlyDataBlobKey, BlobNode>(key =>
            {
                return(new BlobNode(key.Name, ObjectNodeSection.ReadOnlyDataSection, key.Data, key.Alignment));
            });

            _externSymbols = new NodeCache <string, ExternSymbolNode>((string name) =>
            {
                return(new ExternSymbolNode(name));
            });

            _pInvokeModuleFixups = new NodeCache <PInvokeModuleData, PInvokeModuleFixupNode>((PInvokeModuleData moduleData) =>
            {
                return(new PInvokeModuleFixupNode(moduleData));
            });

            _pInvokeMethodFixups = new NodeCache <Tuple <PInvokeModuleData, string, PInvokeFlags>, PInvokeMethodFixupNode>((Tuple <PInvokeModuleData, string, PInvokeFlags> key) =>
            {
                return(new PInvokeMethodFixupNode(key.Item1, key.Item2, key.Item3));
            });

            _methodEntrypoints = new NodeCache <MethodDesc, IMethodNode>(CreateMethodEntrypointNode);

            _unboxingStubs = new NodeCache <MethodDesc, IMethodNode>(CreateUnboxingStubNode);

            _methodAssociatedData = new NodeCache <IMethodNode, MethodAssociatedDataNode>(methodNode =>
            {
                return(new MethodAssociatedDataNode(methodNode));
            });

            _fatFunctionPointers = new NodeCache <MethodKey, FatFunctionPointerNode>(method =>
            {
                return(new FatFunctionPointerNode(method.Method, method.IsUnboxingStub));
            });

            _gvmDependenciesNode = new NodeCache <MethodDesc, GVMDependenciesNode>(method =>
            {
                return(new GVMDependenciesNode(method));
            });

            _gvmTableEntries = new NodeCache <TypeDesc, TypeGVMEntriesNode>(type =>
            {
                return(new TypeGVMEntriesNode(type));
            });

            _reflectableMethods = new NodeCache <MethodDesc, ReflectableMethodNode>(method =>
            {
                return(new ReflectableMethodNode(method));
            });

            _shadowConcreteMethods = new NodeCache <MethodKey, IMethodNode>(methodKey =>
            {
                MethodDesc canonMethod = methodKey.Method.GetCanonMethodTarget(CanonicalFormKind.Specific);

                if (methodKey.IsUnboxingStub)
                {
                    return(new ShadowConcreteUnboxingThunkNode(methodKey.Method, MethodEntrypoint(canonMethod, true)));
                }
                else
                {
                    return(new ShadowConcreteMethodNode(methodKey.Method, MethodEntrypoint(canonMethod)));
                }
            });

            _runtimeDeterminedMethods = new NodeCache <MethodDesc, IMethodNode>(method =>
            {
                return(new RuntimeDeterminedMethodNode(method,
                                                       MethodEntrypoint(method.GetCanonMethodTarget(CanonicalFormKind.Specific))));
            });

            _virtMethods = new NodeCache <MethodDesc, VirtualMethodUseNode>((MethodDesc method) =>
            {
                // We don't need to track virtual method uses for types that have a vtable with a known layout.
                // It's a waste of CPU time and memory.
                Debug.Assert(!VTable(method.OwningType).HasFixedSlots);

                return(new VirtualMethodUseNode(method));
            });

            _readyToRunHelpers = new NodeCache <ReadyToRunHelperKey, ISymbolNode>(CreateReadyToRunHelperNode);

            _genericReadyToRunHelpersFromDict = new NodeCache <ReadyToRunGenericHelperKey, ISymbolNode>(CreateGenericLookupFromDictionaryNode);
            _genericReadyToRunHelpersFromType = new NodeCache <ReadyToRunGenericHelperKey, ISymbolNode>(CreateGenericLookupFromTypeNode);

            _indirectionNodes = new NodeCache <ISortableSymbolNode, ISymbolNode>(indirectedNode =>
            {
                return(new IndirectionNode(Target, indirectedNode, 0));
            });

            _frozenStringNodes = new NodeCache <string, FrozenStringNode>((string data) =>
            {
                return(new FrozenStringNode(data, Target));
            });

            _frozenArrayNodes = new NodeCache <PreInitFieldInfo, FrozenArrayNode>((PreInitFieldInfo fieldInfo) =>
            {
                return(new FrozenArrayNode(fieldInfo));
            });

            _interfaceDispatchCells = new NodeCache <DispatchCellKey, InterfaceDispatchCellNode>(callSiteCell =>
            {
                return(new InterfaceDispatchCellNode(callSiteCell.Target, callSiteCell.CallsiteId));
            });

            _interfaceDispatchMaps = new NodeCache <TypeDesc, InterfaceDispatchMapNode>((TypeDesc type) =>
            {
                return(new InterfaceDispatchMapNode(this, type));
            });

            _sealedVtableNodes = new NodeCache <TypeDesc, SealedVTableNode>((TypeDesc type) =>
            {
                return(new SealedVTableNode(type));
            });

            _runtimeMethodHandles = new NodeCache <MethodDesc, RuntimeMethodHandleNode>((MethodDesc method) =>
            {
                return(new RuntimeMethodHandleNode(method));
            });

            _runtimeFieldHandles = new NodeCache <FieldDesc, RuntimeFieldHandleNode>((FieldDesc field) =>
            {
                return(new RuntimeFieldHandleNode(field));
            });

            _interfaceDispatchMapIndirectionNodes = new NodeCache <TypeDesc, EmbeddedObjectNode>((TypeDesc type) =>
            {
                return(DispatchMapTable.NewNodeWithSymbol(InterfaceDispatchMap(type)));
            });

            _genericCompositions = new NodeCache <GenericCompositionDetails, GenericCompositionNode>((GenericCompositionDetails details) =>
            {
                return(new GenericCompositionNode(details));
            });

            _eagerCctorIndirectionNodes = new NodeCache <MethodDesc, EmbeddedObjectNode>((MethodDesc method) =>
            {
                Debug.Assert(method.IsStaticConstructor);
                Debug.Assert(TypeSystemContext.HasEagerStaticConstructor((MetadataType)method.OwningType));
                return(EagerCctorTable.NewNode(MethodEntrypoint(method)));
            });

            _namedJumpStubNodes = new NodeCache <Tuple <string, ISymbolNode>, NamedJumpStubNode>((Tuple <string, ISymbolNode> id) =>
            {
                return(new NamedJumpStubNode(id.Item1, id.Item2));
            });

            _delegateMarshalingDataNodes = new NodeCache <DefType, DelegateMarshallingDataNode>(type =>
            {
                return(new DelegateMarshallingDataNode(type));
            });

            _structMarshalingDataNodes = new NodeCache <DefType, StructMarshallingDataNode>(type =>
            {
                return(new StructMarshallingDataNode(type));
            });

            _vTableNodes = new NodeCache <TypeDesc, VTableSliceNode>((TypeDesc type ) =>
            {
                if (CompilationModuleGroup.ShouldProduceFullVTable(type))
                {
                    return(new EagerlyBuiltVTableSliceNode(type));
                }
                else
                {
                    return(_vtableSliceProvider.GetSlice(type));
                }
            });

            _methodGenericDictionaries = new NodeCache <MethodDesc, ISortableSymbolNode>(method =>
            {
                if (CompilationModuleGroup.ContainsMethodDictionary(method))
                {
                    return(new MethodGenericDictionaryNode(method, this));
                }
                else
                {
                    return(_importedNodeProvider.ImportedMethodDictionaryNode(this, method));
                }
            });

            _typeGenericDictionaries = new NodeCache <TypeDesc, ISortableSymbolNode>(type =>
            {
                if (CompilationModuleGroup.ContainsTypeDictionary(type))
                {
                    Debug.Assert(!this.LazyGenericsPolicy.UsesLazyGenerics(type));
                    return(new TypeGenericDictionaryNode(type, this));
                }
                else
                {
                    return(_importedNodeProvider.ImportedTypeDictionaryNode(this, type));
                }
            });

            _typesWithMetadata = new NodeCache <MetadataType, TypeMetadataNode>(type =>
            {
                return(new TypeMetadataNode(type));
            });

            _methodsWithMetadata = new NodeCache <MethodDesc, MethodMetadataNode>(method =>
            {
                return(new MethodMetadataNode(method));
            });

            _fieldsWithMetadata = new NodeCache <FieldDesc, FieldMetadataNode>(field =>
            {
                return(new FieldMetadataNode(field));
            });

            _modulesWithMetadata = new NodeCache <ModuleDesc, ModuleMetadataNode>(module =>
            {
                return(new ModuleMetadataNode(module));
            });

            _genericDictionaryLayouts = new NodeCache <TypeSystemEntity, DictionaryLayoutNode>(_dictionaryLayoutProvider.GetLayout);

            _stringAllocators = new NodeCache <MethodDesc, IMethodNode>(constructor =>
            {
                return(new StringAllocatorMethodNode(constructor));
            });

            NativeLayout     = new NativeLayoutHelper(this);
            WindowsDebugData = new WindowsDebugDataHelper(this);
        }
Example #35
0
 internal EcmaAssembly(TypeSystemContext context, PEReader peReader, MetadataReader metadataReader, PdbSymbolReader pdbReader)
     : base(context, peReader, metadataReader, pdbReader)
 {
     _assemblyDefinition = metadataReader.GetAssemblyDefinition();
 }