private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup) { switch (id) { case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEW: case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEWARR_1: case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_ISINSTANCEOF: case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_CHKCAST: return(false); case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ReadyToRunHelper(ReadyToRunHelperId.GetNonGCStaticBase, type)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE: { // Token == 0 means "initialize this class". We only expect RyuJIT to call it for this case. Debug.Assert(pResolvedToken.token == 0 && pResolvedToken.tokenScope == null); Debug.Assert(pGenericLookupKind.needsRuntimeLookup); DefType typeToInitialize = (DefType)MethodBeingCompiled.OwningType; Debug.Assert(typeToInitialize.IsCanonicalSubtype(CanonicalFormKind.Any)); DefType helperArg = typeToInitialize.ConvertToSharedRuntimeDeterminedForm(); ISymbolNode helper = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, ReadyToRunHelperId.GetNonGCStaticBase, helperArg); pLookup = CreateConstLookupToSymbol(helper); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_HANDLE: { Debug.Assert(pGenericLookupKind.needsRuntimeLookup); ReadyToRunHelperId helperId = (ReadyToRunHelperId)pGenericLookupKind.runtimeLookupFlags; object helperArg = HandleToObject((IntPtr)pGenericLookupKind.runtimeLookupArgs); ISymbolNode helper = GetGenericLookupHelper(pGenericLookupKind.runtimeLookupKind, helperId, helperArg); pLookup = CreateConstLookupToSymbol(helper); } break; default: throw new NotImplementedException("ReadyToRun: " + id.ToString()); } return(true); }
private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup) { switch (id) { case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEW: { var type = HandleToObject(pResolvedToken.hClass); Debug.Assert(type.IsDefType); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewHelper, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEWARR_1: { var type = HandleToObject(pResolvedToken.hClass); Debug.Assert(type.IsSzArray); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewArr1, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_ISINSTANCEOF: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } // ECMA-335 III.4.3: If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T if (type.IsNullable) { type = type.Instantiation[0]; } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.IsInstanceOf, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_CHKCAST: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } // ECMA-335 III.4.3: If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T if (type.IsNullable) { type = type.Instantiation[0]; } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.CastClass, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.CctorTrigger, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_HANDLE: { Debug.Assert(pGenericLookupKind.needsRuntimeLookup); ReadyToRunHelperId helperId = (ReadyToRunHelperId)pGenericLookupKind.runtimeLookupFlags; object helperArg = HandleToObject((IntPtr)pGenericLookupKind.runtimeLookupArgs); if (helperArg is MethodDesc methodArg) { helperArg = new MethodWithToken(methodArg, new ModuleToken(_tokenContext, pResolvedToken.token)); } GenericContext methodContext = new GenericContext(entityFromContext(pResolvedToken.tokenContext)); ISymbolNode helper = _compilation.SymbolNodeFactory.GenericLookupHelper( pGenericLookupKind.runtimeLookupKind, helperId, helperArg, methodContext, _signatureContext); pLookup = CreateConstLookupToSymbol(helper); } break; default: throw new NotImplementedException("ReadyToRun: " + id.ToString()); } return(true); }
private bool getReadyToRunHelper(ref CORINFO_RESOLVED_TOKEN pResolvedToken, ref CORINFO_LOOKUP_KIND pGenericLookupKind, CorInfoHelpFunc id, ref CORINFO_CONST_LOOKUP pLookup) { switch (id) { case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEW: { var type = HandleToObject(pResolvedToken.hClass); Debug.Assert(type.IsDefType); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewHelper, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_NEWARR_1: { var type = HandleToObject(pResolvedToken.hClass); Debug.Assert(type.IsSzArray); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.NewArr1, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_ISINSTANCEOF: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } // ECMA-335 III.4.3: If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T if (type.IsNullable) { type = type.Instantiation[0]; } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.IsInstanceOf, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_CHKCAST: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } // ECMA-335 III.4.3: If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T if (type.IsNullable) { type = type.Instantiation[0]; } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.CastClass, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_STATIC_BASE: { var type = HandleToObject(pResolvedToken.hClass); if (type.IsCanonicalSubtype(CanonicalFormKind.Any)) { return(false); } pLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.ReadyToRunHelper(ReadyToRunHelperId.GetNonGCStaticBase, type, _signatureContext)); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE: { // Token == 0 means "initialize this class". We only expect RyuJIT to call it for this case. Debug.Assert(pResolvedToken.token == 0 && pResolvedToken.tokenScope == null); Debug.Assert(pGenericLookupKind.needsRuntimeLookup); DefType typeToInitialize = (DefType)MethodBeingCompiled.OwningType; Debug.Assert(typeToInitialize.IsCanonicalSubtype(CanonicalFormKind.Any)); DefType helperArg = typeToInitialize.ConvertToSharedRuntimeDeterminedForm(); TypeDesc contextType; if (pGenericLookupKind.runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ) { contextType = methodFromContext(pResolvedToken.tokenContext).OwningType; } else { contextType = null; } ISymbolNode helper = _compilation.SymbolNodeFactory.GenericLookupHelper( pGenericLookupKind.runtimeLookupKind, ReadyToRunHelperId.GetNonGCStaticBase, helperArg, contextType, _signatureContext); pLookup = CreateConstLookupToSymbol(helper); } break; case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_GENERIC_HANDLE: { Debug.Assert(pGenericLookupKind.needsRuntimeLookup); ReadyToRunHelperId helperId = (ReadyToRunHelperId)pGenericLookupKind.runtimeLookupFlags; object helperArg = HandleToObject((IntPtr)pGenericLookupKind.runtimeLookupArgs); if (helperArg is MethodDesc methodArg) { helperArg = new MethodWithToken(methodArg, new ModuleToken(_tokenContext, pResolvedToken.token)); } TypeDesc contextType; if (pGenericLookupKind.runtimeLookupKind == CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_THISOBJ) { contextType = methodFromContext(pResolvedToken.tokenContext).OwningType; } else { contextType = null; } ISymbolNode helper = _compilation.SymbolNodeFactory.GenericLookupHelper( pGenericLookupKind.runtimeLookupKind, helperId, helperArg, contextType, _signatureContext); pLookup = CreateConstLookupToSymbol(helper); } break; default: throw new NotImplementedException("ReadyToRun: " + id.ToString()); } return(true); }