1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // ===========================================================================
7 // Signature encoding for zapper (ngen)
10 // ===========================================================================
17 #include "sigbuilder.h"
19 #ifndef DACCESS_COMPILE
21 BOOL ZapSig::GetSignatureForTypeDesc(TypeDesc * desc, SigBuilder * pSigBuilder)
30 CorElementType elemType = desc->GetInternalCorElementType();
32 if (elemType == ELEMENT_TYPE_VALUETYPE)
34 // convert to ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG so that the right
35 // thing will happen in code:SigPointer.GetTypeHandleThrowing
36 elemType = (CorElementType) ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG;
38 else if (elemType == ELEMENT_TYPE_VAR || elemType == ELEMENT_TYPE_MVAR)
40 // Enable encoding of type variables for NGen signature only. IBC toolchain is not aware of them yet.
41 if (context.externalTokens == ZapSig::NormalTokens)
42 elemType = (CorElementType) ELEMENT_TYPE_VAR_ZAPSIG;
45 pSigBuilder->AppendElementType(elemType);
47 if (desc->HasTypeParam())
49 if (!this->GetSignatureForTypeHandle(desc->GetTypeParam(), pSigBuilder))
52 if (elemType == ELEMENT_TYPE_ARRAY)
54 ArrayTypeDesc *pArrayDesc = dac_cast<PTR_ArrayTypeDesc>(desc);
55 _ASSERTE(pArrayDesc->GetRank() != 0);
56 pSigBuilder->AppendData(pArrayDesc->GetRank());
57 pSigBuilder->AppendData(0);
58 pSigBuilder->AppendData(0);
63 switch ((DWORD)elemType)
65 case ELEMENT_TYPE_FNPTR:
67 FnPtrTypeDesc *pTD = dac_cast<PTR_FnPtrTypeDesc>(desc);
69 // Emit calling convention
70 pSigBuilder->AppendByte(pTD->GetCallConv());
73 unsigned numArgs = pTD->GetNumArgs();
74 pSigBuilder->AppendData(numArgs);
76 // return type and args
77 TypeHandle *retAndArgTypes = pTD->GetRetAndArgTypesPointer();
78 for (DWORD i = 0; i <= numArgs; i++)
80 TypeHandle th = retAndArgTypes[i];
81 // This should be a consequence of the type key being restored
82 CONSISTENCY_CHECK(!th.IsNull() && !th.IsEncodedFixup());
83 if (!this->GetSignatureForTypeHandle(th, pSigBuilder))
89 case ELEMENT_TYPE_MVAR:
90 // _ASSERTE(!"Cannot encode ET_MVAR in a ZapSig");
93 case ELEMENT_TYPE_VAR:
94 // _ASSERTE(!"Cannot encode ET_VAR in a ZapSig");
97 case ELEMENT_TYPE_VAR_ZAPSIG:
99 TypeVarTypeDesc * pTypeVarDesc = dac_cast<PTR_TypeVarTypeDesc>(desc);
100 Module * pVarTypeModule = pTypeVarDesc->GetModule();
101 if (pVarTypeModule != this->context.pInfoModule)
103 DWORD index = (*this->pfnEncodeModule)(this->context.pModuleContext, pVarTypeModule);
105 if (index == ENCODE_MODULE_FAILED)
108 // emit the ET_MODULE_ZAPSIG escape
109 pSigBuilder->AppendElementType((CorElementType) ELEMENT_TYPE_MODULE_ZAPSIG);
110 // emit the module index
111 pSigBuilder->AppendData(index);
113 pSigBuilder->AppendData(RidFromToken(pTypeVarDesc->GetToken()));
118 _ASSERTE(!"Bad type");
127 // Create a signature for a typeHandle
128 // It can be decoded using MetaSig::GetTypeHandleThrowing
129 // The tokens are espressed relative to this->pInfoModule
130 // When handle.GetModule() != this->pInfoModule), we escape the signature
131 // with an ELEMENT_TYPE_MODULE_ZAPSIG <id-num> <token> to encode
132 // a temporary change of module
134 // Returns the number of characters written into the buffer.
135 // If buffer and bufferMax are NULL, it returns the number of
136 // characters that would have been written.
137 // If the buffer isn't big enough it doesn't write past bufferMax
138 // A return value of 0 indidates a failure to encode the signature
140 BOOL ZapSig::GetSignatureForTypeHandle(TypeHandle handle,
141 SigBuilder * pSigBuilder)
148 PRECONDITION(CheckPointer(handle));
149 PRECONDITION(CheckPointer(this->context.pInfoModule));
150 PRECONDITION(!handle.HasUnrestoredTypeKey());
155 if (handle.IsTypeDesc())
156 return GetSignatureForTypeDesc(handle.AsTypeDesc(), pSigBuilder);
158 MethodTable *pMT = handle.AsMethodTable();
160 // Can we encode the type using a short ET encoding?
162 CorElementType elemType = TryEncodeUsingShortcut(pMT);
163 if (elemType != ELEMENT_TYPE_END)
165 _ASSERTE(pMT->IsTypicalTypeDefinition());
167 // Check for an array type and encode that we are dealing with a MethodTable representation
168 if (elemType == ELEMENT_TYPE_SZARRAY || elemType == ELEMENT_TYPE_ARRAY)
170 pSigBuilder->AppendElementType((CorElementType)ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG);
171 pSigBuilder->AppendElementType(elemType);
173 TypeHandle elementType = pMT->GetApproxArrayElementTypeHandle();
174 if (!this->GetSignatureForTypeHandle(elementType, pSigBuilder))
177 if (elemType == ELEMENT_TYPE_ARRAY)
179 pSigBuilder->AppendData(pMT->GetRank());
180 pSigBuilder->AppendData(0);
181 pSigBuilder->AppendData(0);
186 pSigBuilder->AppendElementType(elemType);
192 // We could not encode the type using a short encoding
193 // and we have a handle that represents a Class or ValueType
195 // We may need to emit an out-of-module escape sequence
197 Module *pTypeHandleModule = pMT->GetModule_NoLogging();
199 // If the type handle's module is different that the this->pInfoModule
200 // we will need to add an out-of-module escape for the type
203 mdToken token = pMT->GetCl_NoLogging();
204 #ifdef FEATURE_NATIVE_IMAGE_GENERATION
205 if (pTypeHandleModule != this->context.pInfoModule && !pTypeHandleModule->IsInCurrentVersionBubble())
207 pTypeHandleModule = GetAppDomain()->ToCompilationDomain()->GetTargetModule();
208 token = pTypeHandleModule->LookupTypeRefByMethodTable(pMT);
211 if (pTypeHandleModule != this->context.pInfoModule)
213 // During IBC profiling this calls
214 // code:Module.EncodeModuleHelper
215 // During ngen this calls
216 // code:ZapImportTable.EncodeModuleHelper)
218 index = (*this->pfnEncodeModule)(this->context.pModuleContext, pTypeHandleModule);
220 if (index == ENCODE_MODULE_FAILED)
223 // emit the ET_MODULE_ZAPSIG escape
224 pSigBuilder->AppendElementType((CorElementType) ELEMENT_TYPE_MODULE_ZAPSIG);
225 // emit the module index
226 pSigBuilder->AppendData(index);
229 // Remember if we have an instantiated generic type
230 bool fNeedsInstantiation = pMT->HasInstantiation() && !pMT->IsGenericTypeDefinition();
232 // We possibly have an instantiated generic type
233 if (fNeedsInstantiation)
235 pSigBuilder->AppendElementType(ELEMENT_TYPE_GENERICINST);
238 // Beware of enums! Can't use GetInternalCorElementType() here.
239 pSigBuilder->AppendElementType(pMT->IsValueType() ? ELEMENT_TYPE_VALUETYPE : ELEMENT_TYPE_CLASS);
241 _ASSERTE(!IsNilToken(token));
242 if (IsNilToken(token))
245 if ((index != 0) && (this->pfnTokenDefinition != NULL))
248 // We do not want to log the metadata lookups that we perform here
250 IBCLoggingDisabler disableLogging;
252 // During IBC profiling this calls
253 // code:Module::TokenDefinitionHelper
254 (*this->pfnTokenDefinition)(this->context.pModuleContext, pTypeHandleModule, index, &token);
256 // ibcExternalType tokens are actually encoded as mdtTypeDef tokens in the signature
257 _ASSERT(TypeFromToken(token) == ibcExternalType);
258 token = TokenFromRid(RidFromToken(token), mdtTypeDef);
261 pSigBuilder->AppendToken(token);
263 if (fNeedsInstantiation)
265 pSigBuilder->AppendData(pMT->GetNumGenericArgs());
266 Instantiation inst = pMT->GetInstantiation();
267 for (DWORD i = 0; i < inst.GetNumArgs(); i++)
269 TypeHandle t = inst[i];
270 CONSISTENCY_CHECK(!t.IsNull() && !t.IsEncodedFixup());
271 if (!this->GetSignatureForTypeHandle(t, pSigBuilder))
278 #endif // #ifndef DACCESS_COMPILE
281 // Returns element type when the typeHandle can be encoded using
282 // using a single CorElementType value
283 // This includes using ELEMENT_TYPE_CANON_ZAPSIG for the System.__Canon type
285 /*static */ CorElementType ZapSig::TryEncodeUsingShortcut(/* in */ MethodTable * pMT)
287 LIMITED_METHOD_CONTRACT;
289 CorElementType elemType = ELEMENT_TYPE_END; // An illegal value that we check for later
291 // Set elemType to a shortcut encoding whenever possible
293 if (pMT->IsTruePrimitive())
294 elemType = pMT->GetInternalCorElementType();
295 else if (pMT == g_pObjectClass)
296 elemType = ELEMENT_TYPE_OBJECT;
297 else if (pMT == g_pStringClass)
298 elemType = ELEMENT_TYPE_STRING;
299 else if (pMT == g_pCanonMethodTableClass)
300 elemType = (CorElementType) ELEMENT_TYPE_CANON_ZAPSIG;
301 else if (pMT->IsArray())
302 elemType = pMT->GetInternalCorElementType(); // either ELEMENT_TYPE_SZARRAY or ELEMENT_TYPE_ARRAY
308 // Compare a metadata signature element with a type handle
309 // The type handle must have a fully restored type key, which in turn means that modules for all of its
310 // components are loaded (e.g. type arguments to an instantiated type).
312 // Hence we can do the signature comparison without incurring any loads or restores.
314 /*static*/ BOOL ZapSig::CompareSignatureToTypeHandle(PCCOR_SIGNATURE pSig,
317 const ZapSig::Context * pZapSigContext)
325 PRECONDITION(CheckPointer(pModule));
326 PRECONDITION(CheckPointer(pZapSigContext));
327 PRECONDITION(CheckPointer(pZapSigContext->pModuleContext));
328 PRECONDITION(CheckPointer(pZapSigContext->pInfoModule));
329 PRECONDITION(CheckPointer(handle));
330 PRECONDITION(CheckPointer(pSig));
331 PRECONDITION(!handle.HasUnrestoredTypeKey());
338 // pOrigModule is the original module that contained this ZapSig
340 Module * pOrigModule = pZapSigContext->pInfoModule;
341 CorElementType sigType = CorSigUncompressElementType(pSig);
342 CorElementType handleType = handle.GetSignatureCorElementType();
344 switch ((DWORD)sigType)
349 _ASSERTE(!"Unknown type in ZapSig::CompareSignatureToTypeHandle");
353 case ELEMENT_TYPE_MODULE_ZAPSIG:
355 DWORD ix = CorSigUncompressData(pSig);
356 CONTRACT_VIOLATION(ThrowsViolation|GCViolation);
357 pModule = pZapSigContext->GetZapSigModule()->GetModuleFromIndexIfLoaded(ix);
361 RETURN(CompareSignatureToTypeHandle(pSig, pModule, handle, pZapSigContext));
366 case ELEMENT_TYPE_VOID:
367 case ELEMENT_TYPE_I1:
368 case ELEMENT_TYPE_U1:
369 case ELEMENT_TYPE_I2:
370 case ELEMENT_TYPE_U2:
371 case ELEMENT_TYPE_I4:
372 case ELEMENT_TYPE_U4:
373 case ELEMENT_TYPE_I8:
374 case ELEMENT_TYPE_U8:
375 case ELEMENT_TYPE_R4:
376 case ELEMENT_TYPE_R8:
377 case ELEMENT_TYPE_BOOLEAN:
378 case ELEMENT_TYPE_CHAR:
379 case ELEMENT_TYPE_TYPEDBYREF:
380 RETURN(sigType == handleType);
382 case ELEMENT_TYPE_STRING:
383 RETURN(handle == TypeHandle(g_pStringClass));
385 case ELEMENT_TYPE_OBJECT:
386 RETURN(handle == TypeHandle(g_pObjectClass));
388 case ELEMENT_TYPE_CANON_ZAPSIG:
389 RETURN(handle == TypeHandle(g_pCanonMethodTableClass));
391 case ELEMENT_TYPE_VAR:
392 case ELEMENT_TYPE_MVAR:
394 if (sigType != handleType)
397 unsigned varNum = CorSigUncompressData(pSig);
398 RETURN(varNum == (dac_cast<PTR_TypeVarTypeDesc>(handle.AsTypeDesc())->GetIndex()));
401 case ELEMENT_TYPE_VAR_ZAPSIG:
403 if (!handle.IsGenericVariable())
406 TypeVarTypeDesc *pTypeVarTypeDesc = handle.AsGenericVariable();
408 unsigned rid = CorSigUncompressData(pSig);
409 RETURN(TokenFromRid(rid, mdtGenericParam) == pTypeVarTypeDesc->GetToken() && pModule == pTypeVarTypeDesc->GetModule());
412 // These take an additional argument, which is the element type
413 case ELEMENT_TYPE_SZARRAY:
414 case ELEMENT_TYPE_PTR:
415 case ELEMENT_TYPE_BYREF:
417 if (sigType != handleType)
420 RETURN (CompareSignatureToTypeHandle(pSig, pModule, handle.GetTypeParam(), pZapSigContext));
423 case ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG:
425 if (handle.IsTypeDesc() || !handle.AsMethodTable()->IsArray())
428 RETURN (CompareSignatureToTypeHandle(pSig, pModule, handle, pZapSigContext));
431 case ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG:
433 sigType = CorSigUncompressElementType(pSig);
434 _ASSERTE(sigType == ELEMENT_TYPE_VALUETYPE);
436 if (!handle.IsNativeValueType()) RETURN(FALSE);
439 case ELEMENT_TYPE_VALUETYPE:
440 case ELEMENT_TYPE_CLASS:
442 CorSigUncompressToken(pSig, &tk);
443 if (TypeFromToken(tk) == mdtTypeRef)
445 BOOL resolved = FALSE;
448 ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
449 resolved = ClassLoader::ResolveTokenToTypeDefThrowing(pModule, tk, &pModule, &tk, Loader::DontLoad);
454 EX_END_CATCH(SwallowAllExceptions);
458 _ASSERTE(TypeFromToken(tk) == mdtTypeDef);
459 RETURN (sigType == handleType && !handle.HasInstantiation() && pModule == handle.GetModule() && handle.GetCl() == tk);
462 case ELEMENT_TYPE_FNPTR:
464 if (sigType != handleType)
467 FnPtrTypeDesc *pTD = handle.AsFnPtrType();
468 DWORD callConv = CorSigUncompressData(pSig);
469 if (callConv != pTD->GetCallConv())
472 DWORD numArgs = CorSigUncompressData(pSig);
473 if (numArgs != pTD->GetNumArgs())
477 CONTRACT_VIOLATION(ThrowsViolation|GCViolation);
479 for (DWORD i = 0; i <= numArgs; i++)
482 if (!CompareSignatureToTypeHandle(pSig, pOrigModule, pTD->GetRetAndArgTypes()[i], pZapSigContext))
484 if (FAILED(sp.SkipExactlyOne()))
494 case ELEMENT_TYPE_GENERICINST:
496 if (!handle.HasInstantiation())
499 sigType = CorSigUncompressElementType(pSig);
500 if (sigType != handleType)
503 pSig += CorSigUncompressToken(pSig, &tk);
504 if (TypeFromToken(tk) == mdtTypeRef)
506 BOOL resolved = FALSE;
509 ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
510 resolved = ClassLoader::ResolveTokenToTypeDefThrowing(pModule, tk, &pModule, &tk, Loader::DontLoad);
515 EX_END_CATCH(SwallowAllExceptions);
519 _ASSERTE(TypeFromToken(tk) == mdtTypeDef);
520 if (pModule != handle.GetModule() || tk != handle.GetCl())
523 DWORD numGenericArgs = CorSigUncompressData(pSig);
525 if (numGenericArgs != handle.GetNumGenericArgs())
528 Instantiation inst = handle.GetInstantiation();
529 for (DWORD i = 0; i < inst.GetNumArgs(); i++)
532 if (!CompareSignatureToTypeHandle(pSig, pOrigModule, inst[i], pZapSigContext))
534 if (FAILED(sp.SkipExactlyOne()))
543 case ELEMENT_TYPE_ARRAY:
545 if (sigType != handleType)
548 if (!CompareSignatureToTypeHandle(pSig, pModule, handle.GetTypeParam(), pZapSigContext))
551 if (FAILED(sp.SkipExactlyOne()))
555 if (FAILED(sp.GetData(&rank)))
558 if (rank != handle.AsArray()->GetRank())
568 #ifdef FEATURE_PREJIT
570 BOOL ZapSig::CompareFixupToTypeHandle(Module * pModule, TADDR fixup, TypeHandle handle)
578 PRECONDITION(CORCOMPILE_IS_POINTER_TAGGED(fixup));
579 PRECONDITION(CheckPointer(pModule));
583 Module *pDefiningModule;
584 PCCOR_SIGNATURE pSig = pModule->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule);
585 if (pDefiningModule == NULL)
588 ZapSig::Context zapSigContext(pDefiningModule, pModule);
589 return ZapSig::CompareSignatureToTypeHandle(pSig, pDefiningModule, handle, &zapSigContext);
591 #endif // FEATURE_PREJIT
594 BOOL ZapSig::CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle typeHnd2)
602 PRECONDITION(CheckPointer(pTypeHnd));
603 PRECONDITION(CheckPointer(typeHnd2));
604 PRECONDITION(!CORCOMPILE_IS_POINTER_TAGGED((SIZE_T) typeHnd2.AsPtr()));
608 // Ensure that the compiler won't fetch the value twice
609 SIZE_T fixup = VolatileLoadWithoutBarrier((SIZE_T *)pTypeHnd);
611 #ifdef FEATURE_PREJIT
612 if (CORCOMPILE_IS_POINTER_TAGGED(fixup))
614 Module *pContainingModule = ExecutionManager::FindZapModule(dac_cast<TADDR>(pTypeHnd));
615 CONSISTENCY_CHECK(pContainingModule != NULL);
617 Module *pDefiningModule;
618 PCCOR_SIGNATURE pSig = pContainingModule->GetEncodedSigIfLoaded(CORCOMPILE_UNTAG_TOKEN(fixup), &pDefiningModule);
619 if (pDefiningModule == NULL)
623 ZapSig::Context zapSigContext(pDefiningModule, pContainingModule);
624 ZapSig::Context * pZapSigContext = &zapSigContext;
625 return CompareSignatureToTypeHandle(pSig, pDefiningModule, typeHnd2, pZapSigContext);
629 #endif // FEATURE_PREJIT
630 return TypeHandle::FromTAddr(fixup) == typeHnd2;
633 #ifndef DACCESS_COMPILE
634 Module *ZapSig::DecodeModuleFromIndex(Module *fromModule,
645 Assembly *pAssembly = NULL;
649 pAssembly = fromModule->GetAssembly();
653 if (index < fromModule->GetAssemblyRefMax())
655 pAssembly = fromModule->LoadAssembly(RidToToken(index, mdtAssemblyRef))->GetAssembly();
659 index -= fromModule->GetAssemblyRefMax();
661 pAssembly = fromModule->GetNativeMetadataAssemblyRefFromCache(index);
663 if(pAssembly == NULL)
666 spec.InitializeSpec(TokenFromRid(index, mdtAssemblyRef),
667 fromModule->GetNativeAssemblyImport(),
670 pAssembly = spec.LoadAssembly(FILE_LOADED);
672 fromModule->SetNativeMetadataAssemblyRefInCache(index, pAssembly);
677 return pAssembly->GetManifestModule();
680 Module *ZapSig::DecodeModuleFromIndexIfLoaded(Module *fromModule,
691 Assembly *pAssembly = NULL;
692 mdAssemblyRef tkAssemblyRef;
695 pAssembly = fromModule->GetAssembly();
698 if (index < fromModule->GetAssemblyRefMax())
700 tkAssemblyRef = RidToToken(index, mdtAssemblyRef);
701 pAssembly = fromModule->GetAssemblyIfLoaded(tkAssemblyRef);
705 index -= fromModule->GetAssemblyRefMax();
706 tkAssemblyRef = RidToToken(index, mdtAssemblyRef);
707 IMDInternalImport * pMDImportOverride = fromModule->GetNativeAssemblyImport(FALSE);
708 if (pMDImportOverride != NULL)
710 CHAR szFullName[MAX_CLASS_NAME + 1];
711 LPCSTR szWinRtNamespace = NULL;
712 LPCSTR szWinRtClassName = NULL;
714 BOOL fValidAssemblyRef = TRUE;
715 LPCSTR pAssemblyName;
717 if (FAILED(pMDImportOverride->GetAssemblyRefProps(tkAssemblyRef,
725 { // Unexpected failure reading MetaData
726 fValidAssemblyRef = FALSE;
729 if (fValidAssemblyRef && IsAfContentType_WindowsRuntime(dwFlags))
731 // Find the encoded type name
732 LPCSTR pTypeName = NULL;
733 if (pAssemblyName != NULL)
734 pTypeName = strchr(pAssemblyName, '!');
736 if (pTypeName != NULL)
739 // pTypeName now contains the full type name (namespace + name)
741 strcpy_s(szFullName, _countof(szFullName), pTypeName);
742 LPSTR pszName = strrchr(szFullName, '.');
744 // WinRT types must have a namespace
747 // Replace . between namespace and name with null terminator.
748 // This breaks the string into a namespace and name pair.
752 szWinRtNamespace = szFullName;
753 szWinRtClassName = pszName;
756 { // Namespace '.' separator not found - invalid type name (namespace has to be always present)
757 fValidAssemblyRef = FALSE;
761 { // Type name separator in assembly name '!' not found
762 fValidAssemblyRef = FALSE;
766 if (fValidAssemblyRef)
768 pAssembly = fromModule->GetAssemblyIfLoaded(
778 if (pAssembly == NULL)
781 return pAssembly->GetManifestModule();
785 TypeHandle ZapSig::DecodeType(Module *pEncodeModuleContext,
787 PCCOR_SIGNATURE pBuffer,
788 ClassLoadLevel level)
798 SigPointer p(pBuffer);
800 ZapSig::Context zapSigContext(pInfoModule, pEncodeModuleContext);
801 ZapSig::Context * pZapSigContext = &zapSigContext;
803 SigTypeContext typeContext; // empty context is OK: encoding should not contain type variables.
805 TypeHandle th = p.GetTypeHandleThrowing(pInfoModule,
807 ClassLoader::LoadTypes,
809 level < CLASS_LOADED, // For non-full loads, drop a level when loading generic arguments
816 MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule,
818 PCCOR_SIGNATURE pBuffer,
819 TypeHandle * ppTH /*=NULL*/)
821 STANDARD_VM_CONTRACT;
823 SigTypeContext typeContext; // empty context is OK: encoding should not contain type variables.
825 return DecodeMethod(pReferencingModule, pInfoModule, pBuffer, &typeContext, ppTH);
828 MethodDesc *ZapSig::DecodeMethod(Module *pReferencingModule,
830 PCCOR_SIGNATURE pBuffer,
831 SigTypeContext *pContext,
832 TypeHandle *ppTH, /*=NULL*/
833 PCCOR_SIGNATURE *ppOwnerTypeSpecWithVars, /*=NULL*/
834 PCCOR_SIGNATURE *ppMethodSpecWithVars /*=NULL*/)
836 STANDARD_VM_CONTRACT;
838 MethodDesc *pMethod = NULL;
840 SigPointer sig(pBuffer);
842 ZapSig::Context zapSigContext(pInfoModule, (void *)pReferencingModule, ZapSig::NormalTokens);
843 ZapSig::Context * pZapSigContext = &zapSigContext;
847 IfFailThrow(sig.GetData(&methodFlags));
849 TypeHandle thOwner = NULL;
851 if ( methodFlags & ENCODE_METHOD_SIG_OwnerType )
853 if (ppOwnerTypeSpecWithVars != NULL)
854 *ppOwnerTypeSpecWithVars = sig.GetPtr();
856 thOwner = sig.GetTypeHandleThrowing(pInfoModule,
858 ClassLoader::LoadTypes,
864 IfFailThrow(sig.SkipExactlyOne());
867 if ( methodFlags & ENCODE_METHOD_SIG_SlotInsteadOfToken )
869 // get the method desc using slot number
871 IfFailThrow(sig.GetData(&slot));
873 _ASSERTE(!thOwner.IsNull());
875 pMethod = thOwner.GetMethodTable()->GetMethodDescForSlot(slot);
880 // decode method token
883 IfFailThrow(sig.GetData(&rid));
885 if (methodFlags & ENCODE_METHOD_SIG_MemberRefToken)
887 if (thOwner.IsNull())
890 MethodDesc * pMD = NULL;
891 FieldDesc * pFD = NULL;
893 MemberLoader::GetDescFromMemberRef(pInfoModule, TokenFromRid(rid, mdtMemberRef), &pMD, &pFD, NULL, FALSE, &th);
894 _ASSERTE(pMD != NULL);
901 pMethod = MemberLoader::GetMethodDescFromMemberRefAndType(pInfoModule, TokenFromRid(rid, mdtMemberRef), thOwner.GetMethodTable());
906 pMethod = MemberLoader::GetMethodDescFromMethodDef(pInfoModule, TokenFromRid(rid, mdtMethodDef), FALSE);
910 if (thOwner.IsNull())
911 thOwner = pMethod->GetMethodTable();
916 // Ensure that the methoddescs dependencies have been walked sufficiently for type forwarders to be resolved.
917 // This method is actually basically a nop for dependencies which are ngen'd, but is real work for jitted
918 // dependencies. (However, this shouldn't be meaningful work that wouldn't happen in any case very soon.)
919 pMethod->PrepareForUseAsADependencyOfANativeImage();
923 // Instantiate the method if needed, or create a stub to a static method in a generic class.
924 if (methodFlags & ENCODE_METHOD_SIG_MethodInstantiation)
926 if (ppMethodSpecWithVars != NULL)
927 *ppMethodSpecWithVars = sig.GetPtr();
930 IfFailThrow(sig.GetData(&nargs));
935 if (!ClrSafeInt<SIZE_T>::multiply(nargs, sizeof(TypeHandle), cbMem/* passed by ref */))
936 ThrowHR(COR_E_OVERFLOW);
938 TypeHandle * pInst = (TypeHandle*) _alloca(cbMem);
940 for (DWORD i = 0; i < nargs; i++)
942 pInst[i] = sig.GetTypeHandleThrowing(pInfoModule,
944 ClassLoader::LoadTypes,
949 IfFailThrow(sig.SkipExactlyOne());
952 inst = Instantiation(pInst, nargs);
956 inst = pMethod->GetMethodInstantiation();
960 // This must be called even if nargs == 0, in order to create an instantiating
961 // stub for static methods in generic classees if needed, also for BoxedEntryPointStubs
962 // in non-generic structs.
963 BOOL isInstantiatingStub = (methodFlags & ENCODE_METHOD_SIG_InstantiatingStub);
964 BOOL isUnboxingStub = (methodFlags & ENCODE_METHOD_SIG_UnboxingStub);
966 pMethod = MethodDesc::FindOrCreateAssociatedMethodDesc(pMethod, thOwner.GetMethodTable(),
969 !(isInstantiatingStub || isUnboxingStub));
971 g_IBCLogger.LogMethodDescAccess(pMethod);
973 if (methodFlags & ENCODE_METHOD_SIG_Constrained)
975 TypeHandle constrainedType = sig.GetTypeHandleThrowing(pInfoModule,
977 ClassLoader::LoadTypes,
983 MethodDesc * directMethod = constrainedType.GetMethodTable()->TryResolveConstraintMethodApprox(thOwner.GetMethodTable(), pMethod);
984 if (directMethod == NULL)
986 // Method on value type was removed. Boxing stub would need to be generated to handle this case.
987 _ASSERTE(!"Constrained method resolution failed");
989 MemberLoader::ThrowMissingMethodException(constrainedType.GetMethodTable(), NULL, NULL, NULL, 0, NULL);
992 // Strip the instantiating stub if the signature did not ask for one
993 if (directMethod->IsInstantiatingStub() && !isInstantiatingStub)
995 pMethod = directMethod->GetWrappedMethodDesc();
999 pMethod = directMethod;
1006 FieldDesc * ZapSig::DecodeField(Module *pReferencingModule,
1007 Module *pInfoModule,
1008 PCCOR_SIGNATURE pBuffer,
1009 TypeHandle *ppTH /*=NULL*/)
1019 SigTypeContext typeContext; // empty context is OK: encoding should not contain type variables.
1021 return DecodeField(pReferencingModule, pInfoModule, pBuffer, &typeContext, ppTH);
1024 FieldDesc * ZapSig::DecodeField(Module *pReferencingModule,
1025 Module *pInfoModule,
1026 PCCOR_SIGNATURE pBuffer,
1027 SigTypeContext *pContext,
1028 TypeHandle *ppTH /*=NULL*/)
1038 FieldDesc *pField = NULL;
1040 SigPointer sig(pBuffer);
1043 IfFailThrow(sig.GetData(&fieldFlags));
1045 MethodTable *pOwnerMT = NULL;
1047 if (fieldFlags & ENCODE_FIELD_SIG_OwnerType)
1049 ZapSig::Context zapSigContext(pInfoModule, pReferencingModule);
1050 ZapSig::Context * pZapSigContext = &zapSigContext;
1052 pOwnerMT = sig.GetTypeHandleThrowing(pInfoModule,
1054 ClassLoader::LoadTypes,
1058 pZapSigContext).GetMethodTable();
1060 IfFailThrow(sig.SkipExactlyOne());
1063 if (fieldFlags & ENCODE_FIELD_SIG_IndexInsteadOfToken)
1065 // get the field desc using index
1067 IfFailThrow(sig.GetData(&fieldIndex));
1069 _ASSERTE(pOwnerMT != NULL);
1071 pField = pOwnerMT->GetFieldDescByIndex(fieldIndex);
1072 _ASSERTE(pOwnerMT == pField->GetApproxEnclosingMethodTable());
1077 IfFailThrow(sig.GetData(&rid));
1079 if (fieldFlags & ENCODE_FIELD_SIG_MemberRefToken)
1081 if (pOwnerMT == NULL)
1084 MethodDesc * pMD = NULL;
1085 FieldDesc * pFD = NULL;
1087 MemberLoader::GetDescFromMemberRef(pInfoModule, TokenFromRid(rid, mdtMemberRef), &pMD, &pFD, NULL, FALSE, &th);
1088 _ASSERTE(pFD != NULL);
1094 pField = MemberLoader::GetFieldDescFromMemberRefAndType(pInfoModule, TokenFromRid(rid, mdtMemberRef), pOwnerMT);
1099 pField = MemberLoader::GetFieldDescFromFieldDef(pInfoModule, TokenFromRid(rid, mdtFieldDef), FALSE);
1104 *ppTH = (pOwnerMT != NULL) ? pOwnerMT : pField->GetApproxEnclosingMethodTable();
1109 // Copy single type signature, adding ELEMENT_TYPE_MODULE_ZAPSIG to types that are encoded using tokens.
1110 // The check for types that use token is conservative in the sense that it adds the override for types
1111 // it doesn't explicitly recognize.
1112 // The source signature originates from the module with index specified by the parameter moduleIndex.
1113 // Passing moduleIndex set to MODULE_INDEX_NONE results in pure copy of the signature.
1115 // NOTE: This function is meant to process only generic signatures that occur as owner type,
1116 // constraint types and method instantiation in the EncodeMethod and EncodeField methods below.
1118 void ZapSig::CopyTypeSignature(SigParser* pSigParser, SigBuilder* pSigBuilder, DWORD moduleIndex)
1120 if (moduleIndex != MODULE_INDEX_NONE)
1123 IfFailThrow(pSigParser->PeekByte(&type));
1125 // Handle single and multidimensional arrays
1126 if (type == ELEMENT_TYPE_SZARRAY || type == ELEMENT_TYPE_ARRAY)
1128 IfFailThrow(pSigParser->GetByte(&type));
1129 pSigBuilder->AppendElementType((CorElementType)type);
1131 // Copy the element type signature
1132 CopyTypeSignature(pSigParser, pSigBuilder, moduleIndex);
1134 if (type == ELEMENT_TYPE_ARRAY)
1138 IfFailThrow(pSigParser->GetData(&rank));
1139 pSigBuilder->AppendData(rank);
1145 IfFailThrow(pSigParser->GetData(&nsizes));
1146 pSigBuilder->AppendData(nsizes);
1152 IfFailThrow(pSigParser->GetData(&size));
1153 pSigBuilder->AppendData(size);
1156 // Copy # of lower bounds
1158 IfFailThrow(pSigParser->GetData(&nlbounds));
1159 pSigBuilder->AppendData(nlbounds);
1164 IfFailThrow(pSigParser->GetData(&lbound));
1165 pSigBuilder->AppendData(lbound);
1173 // The following elements are not expected in the signatures this function processes. They are followed by
1174 if (type == ELEMENT_TYPE_BYREF || type == ELEMENT_TYPE_PTR || type == ELEMENT_TYPE_PINNED ||
1175 type == ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG || type == ELEMENT_TYPE_NATIVE_VALUETYPE_ZAPSIG)
1180 // Add the module zapsig only for types that use tokens.
1181 if (type >= ELEMENT_TYPE_PTR && type != ELEMENT_TYPE_I && type != ELEMENT_TYPE_U && type != ELEMENT_TYPE_OBJECT &&
1182 type != ELEMENT_TYPE_VAR && type != ELEMENT_TYPE_MVAR && type != ELEMENT_TYPE_TYPEDBYREF)
1184 pSigBuilder->AppendElementType((CorElementType)ELEMENT_TYPE_MODULE_ZAPSIG);
1185 pSigBuilder->AppendData(moduleIndex);
1188 // Generic instantiation requires processing each nesting level separately
1189 if (type == ELEMENT_TYPE_GENERICINST)
1191 IfFailThrow(pSigParser->GetByte(&type));
1192 _ASSERTE(type == ELEMENT_TYPE_GENERICINST);
1193 pSigBuilder->AppendElementType((CorElementType)type);
1195 IfFailThrow(pSigParser->GetByte(&type));
1196 _ASSERTE((type == ELEMENT_TYPE_CLASS) || (type == ELEMENT_TYPE_VALUETYPE));
1197 pSigBuilder->AppendElementType((CorElementType)type);
1200 IfFailThrow(pSigParser->GetToken(&token));
1201 pSigBuilder->AppendToken(token);
1203 ULONG argCnt; // Get number of generic parameters
1204 IfFailThrow(pSigParser->GetData(&argCnt));
1205 pSigBuilder->AppendData(argCnt);
1209 CopyTypeSignature(pSigParser, pSigBuilder, moduleIndex);
1216 PCCOR_SIGNATURE typeSigStart = pSigParser->GetPtr();
1217 IfFailThrow(pSigParser->SkipExactlyOne());
1218 PCCOR_SIGNATURE typeSigEnd = pSigParser->GetPtr();
1219 pSigBuilder->AppendBlob((PVOID)typeSigStart, typeSigEnd - typeSigStart);
1223 BOOL ZapSig::EncodeMethod(
1224 MethodDesc * pMethod,
1225 Module * pInfoModule,
1226 SigBuilder * pSigBuilder,
1227 LPVOID pEncodeModuleContext,
1228 ENCODEMODULE_CALLBACK pfnEncodeModule,
1229 DEFINETOKEN_CALLBACK pfnDefineToken,
1230 CORINFO_RESOLVED_TOKEN * pResolvedToken,
1231 CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
1232 BOOL fEncodeUsingResolvedTokenSpecStreams)
1242 TypeHandle ownerType;
1244 #ifdef FEATURE_READYTORUN_COMPILER
1246 // For methods encoded outside of the version bubble, we use pResolvedToken which describes the metadata token from which the method originated
1247 // For tokens inside the version bubble we are not constrained by the contents of pResolvedToken and as such we skip this codepath
1248 // Generic interfaces in canonical form are an exception, we need to get the real type from the pResolvedToken so that the lookup at runtime
1249 // can find the type in interface map.
1250 // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented.
1251 if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble() || (pMethod->IsSharedByGenericInstantiations() && pMethod->IsInterface())))
1253 if (pMethod->IsNDirect())
1255 ownerType = pMethod->GetMethodTable_NoLogging();
1259 if (pResolvedToken == NULL)
1261 _ASSERTE(!"CORINFO_RESOLVED_TOKEN required to encode method!");
1265 // Encode the referencing method type
1266 ownerType = TypeHandle(pResolvedToken->hClass);
1272 ownerType = pMethod->GetMethodTable_NoLogging();
1275 ZapSig::ExternalTokens externalTokens = ZapSig::NormalTokens;
1276 if (pfnDefineToken != NULL)
1278 externalTokens = ZapSig::IbcTokens;
1281 ZapSig zapSig(pInfoModule, pEncodeModuleContext, externalTokens,
1282 (EncodeModuleCallback) pfnEncodeModule,
1283 (TokenDefinitionCallback) pfnDefineToken);
1286 // output the sequence that represents the token for the method
1288 mdMethodDef methodToken = pMethod->GetMemberDef_NoLogging();
1289 DWORD methodFlags = 0;
1290 BOOL fMethodNeedsInstantiation = pMethod->HasMethodInstantiation() && !pMethod->IsGenericMethodDefinition();
1292 if (pMethod->IsUnboxingStub())
1293 methodFlags |= ENCODE_METHOD_SIG_UnboxingStub;
1294 if (pMethod->IsInstantiatingStub())
1295 methodFlags |= ENCODE_METHOD_SIG_InstantiatingStub;
1296 if (fMethodNeedsInstantiation)
1297 methodFlags |= ENCODE_METHOD_SIG_MethodInstantiation;
1300 // For backward compatibility, IBC tokens use slightly different encoding:
1301 // - Owning type is uncoditionally encoded
1302 // - Number of method instantiation arguments is not encoded
1304 if (externalTokens == ZapSig::IbcTokens)
1306 // The type is always encoded before flags for IBC
1307 if (!zapSig.GetSignatureForTypeHandle(ownerType, pSigBuilder))
1312 // Assume that the owner type is going to be needed
1313 methodFlags |= ENCODE_METHOD_SIG_OwnerType;
1316 #ifdef FEATURE_READYTORUN_COMPILER
1317 if (IsReadyToRunCompilation() && (pConstrainedResolvedToken != NULL))
1319 methodFlags |= ENCODE_METHOD_SIG_Constrained;
1322 // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented.
1323 if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble()))
1325 Module * pReferencingModule = pMethod->IsNDirect() ?
1326 pMethod->GetModule() :
1327 (Module *)pResolvedToken->tokenScope;
1329 if (!pReferencingModule->IsInCurrentVersionBubble())
1331 // FUTURE: Encoding of new cross-module references for ReadyToRun
1332 // This warning is hit for recursive cross-module inlining. It is commented out to avoid noise.
1333 // GetSvcLogger()->Printf(W("ReadyToRun: Method reference outside of current version bubble cannot be encoded\n"));
1337 methodToken = pMethod->IsNDirect() ?
1338 pMethod->GetMemberDef_NoLogging() :
1339 pResolvedToken->token;
1341 if (TypeFromToken(methodToken) == mdtMethodSpec)
1343 IfFailThrow(pReferencingModule->GetMDImport()->GetMethodSpecProps(methodToken, &methodToken, NULL, NULL));
1346 switch (TypeFromToken(methodToken))
1349 _ASSERTE(pMethod->IsNDirect() || pResolvedToken->pTypeSpec == NULL);
1350 if (!ownerType.HasInstantiation() || ownerType.IsTypicalTypeDefinition())
1352 methodFlags &= ~ENCODE_METHOD_SIG_OwnerType;
1357 _ASSERTE(pResolvedToken != NULL);
1358 methodFlags |= ENCODE_METHOD_SIG_MemberRefToken;
1360 if (pResolvedToken->pTypeSpec == NULL)
1362 methodFlags &= ~ENCODE_METHOD_SIG_OwnerType;
1365 if (!(methodFlags & ENCODE_METHOD_SIG_InstantiatingStub))
1367 if (SigPointer(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec).IsPolyType(NULL) == hasNoVars)
1368 methodFlags &= ~ENCODE_METHOD_SIG_OwnerType;
1373 _ASSERTE(!"Unexpected method token type!");
1379 if (IsNilToken(methodToken))
1381 methodFlags |= ENCODE_METHOD_SIG_SlotInsteadOfToken;
1384 if (!pMethod->GetModule()->IsInCurrentVersionBubble())
1386 // Using a method defined in another version bubble. We can assume the slot number is stable only for real interface methods.
1387 if (!ownerType.IsInterface() || pMethod->IsStatic() || pMethod->HasMethodInstantiation())
1389 // FUTURE TODO: Version resilience
1390 _ASSERTE(!"References to non-interface methods not yet supported in version resilient images");
1391 IfFailThrow(E_FAIL);
1393 methodFlags |= ENCODE_METHOD_SIG_SlotInsteadOfToken;
1397 Module * pTypeHandleModule = pMethod->GetModule();
1399 if (pTypeHandleModule != pInfoModule)
1401 // During IBC profiling this calls
1402 // code:Module.EncodeModuleHelper
1403 // During ngen this calls
1404 // code:ZapImportTable.EncodeModuleHelper)
1406 DWORD index = (*((EncodeModuleCallback) pfnEncodeModule))(pEncodeModuleContext, pTypeHandleModule);
1408 if (index == ENCODE_MODULE_FAILED)
1413 // If the method handle's module is different that the pInfoModule
1414 // we need to call the TokenDefinitionCallback function
1415 // to record the names for the external module tokens
1417 if ((index != 0) && (pfnDefineToken != NULL))
1420 // We do not want to log the metadata lookups that we perform here
1422 IBCLoggingDisabler disableLogging;
1424 // During IBC profiling this calls
1425 // code:Module::TokenDefinitionHelper()
1426 (*((TokenDefinitionCallback) pfnDefineToken))(pEncodeModuleContext, pTypeHandleModule, index, &methodToken);
1431 _ASSERTE(pInfoModule == pMethod->GetModule());
1434 if (!ownerType.HasInstantiation())
1435 methodFlags &= ~ENCODE_METHOD_SIG_OwnerType;
1441 pSigBuilder->AppendData(methodFlags);
1443 if (methodFlags & ENCODE_METHOD_SIG_OwnerType)
1445 if (fEncodeUsingResolvedTokenSpecStreams && pResolvedToken != NULL && pResolvedToken->pTypeSpec != NULL)
1447 _ASSERTE(pResolvedToken->cbTypeSpec > 0);
1449 DWORD moduleIndex = MODULE_INDEX_NONE;
1450 if ((IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope))
1452 moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
1455 SigParser sigParser(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
1456 CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex);
1460 if (!zapSig.GetSignatureForTypeHandle(ownerType, pSigBuilder))
1465 if ((methodFlags & ENCODE_METHOD_SIG_SlotInsteadOfToken) == 0)
1468 pSigBuilder->AppendData(RidFromToken(methodToken));
1472 // have no token (e.g. it could be an array), encode slot number
1473 pSigBuilder->AppendData(pMethod->GetSlot());
1476 if ((methodFlags & ENCODE_METHOD_SIG_MethodInstantiation) != 0)
1478 if (fEncodeUsingResolvedTokenSpecStreams && pResolvedToken != NULL && pResolvedToken->pMethodSpec != NULL)
1480 _ASSERTE(pResolvedToken->cbMethodSpec > 1);
1482 // Copy the pResolvedToken->pMethodSpec, inserting ELEMENT_TYPE_MODULE_ZAPSIG in front of each type parameter in needed
1483 SigParser sigParser(pResolvedToken->pMethodSpec, pResolvedToken->cbMethodSpec);
1484 BYTE callingConvention;
1485 IfFailThrow(sigParser.GetByte(&callingConvention));
1486 if (callingConvention != (BYTE)IMAGE_CEE_CS_CALLCONV_GENERICINST)
1488 ThrowHR(COR_E_BADIMAGEFORMAT);
1492 IfFailThrow(sigParser.GetData(&numGenArgs));
1493 pSigBuilder->AppendData(numGenArgs);
1495 DWORD moduleIndex = MODULE_INDEX_NONE;
1496 if ((IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope))
1498 moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
1501 while (numGenArgs != 0)
1503 CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex);
1509 Instantiation inst = pMethod->GetMethodInstantiation();
1511 // Number of method instantiation arguments is not encoded in IBC tokens - see comment above
1512 if (externalTokens != ZapSig::IbcTokens)
1513 pSigBuilder->AppendData(inst.GetNumArgs());
1515 for (DWORD i = 0; i < inst.GetNumArgs(); i++)
1517 TypeHandle t = inst[i];
1518 _ASSERTE(!t.IsNull());
1520 if (!zapSig.GetSignatureForTypeHandle(t, pSigBuilder))
1526 #ifdef FEATURE_READYTORUN_COMPILER
1527 if ((methodFlags & ENCODE_METHOD_SIG_Constrained) != 0)
1529 if (fEncodeUsingResolvedTokenSpecStreams && pConstrainedResolvedToken->pTypeSpec != NULL)
1531 _ASSERTE(pConstrainedResolvedToken->cbTypeSpec > 0);
1533 DWORD moduleIndex = (DWORD)-1;
1534 if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pConstrainedResolvedToken->tokenScope)
1536 moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pConstrainedResolvedToken->tokenScope);
1539 SigParser sigParser(pConstrainedResolvedToken->pTypeSpec, pConstrainedResolvedToken->cbTypeSpec);
1540 CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex);
1544 if (!zapSig.GetSignatureForTypeHandle(TypeHandle(pConstrainedResolvedToken->hClass), pSigBuilder))
1553 void ZapSig::EncodeField(
1555 Module *pInfoModule,
1556 SigBuilder *pSigBuilder,
1557 LPVOID pEncodeModuleContext,
1558 ENCODEMODULE_CALLBACK pfnEncodeModule,
1559 CORINFO_RESOLVED_TOKEN *pResolvedToken,
1560 BOOL fEncodeUsingResolvedTokenSpecStreams)
1572 mdMethodDef fieldToken = pField->GetMemberDef();
1573 DWORD fieldFlags = ENCODE_FIELD_SIG_OwnerType;
1575 #ifdef FEATURE_READYTORUN_COMPILER
1576 if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pField->GetModule()->IsInCurrentVersionBubble()))
1578 if (pResolvedToken == NULL)
1580 _ASSERTE(!"CORINFO_RESOLVED_TOKEN required to encode field!");
1584 // Encode the referencing field type
1585 pMT = (MethodTable *)(pResolvedToken->hClass);
1587 Module * pReferencingModule = (Module *)pResolvedToken->tokenScope;
1589 if (!pReferencingModule->IsInCurrentVersionBubble())
1591 // FUTURE: Encoding of new cross-module references for ReadyToRun
1592 // This warning is hit for recursive cross-module inlining. It is commented out to avoid noise.
1593 // GetSvcLogger()->Printf(W("ReadyToRun: Field reference outside of current version bubble cannot be encoded\n"));
1596 _ASSERTE(pReferencingModule == GetAppDomain()->ToCompilationDomain()->GetTargetModule());
1598 fieldToken = pResolvedToken->token;
1600 switch (TypeFromToken(fieldToken))
1603 _ASSERTE(pResolvedToken->pTypeSpec == NULL);
1604 fieldFlags &= ~ENCODE_FIELD_SIG_OwnerType;
1608 fieldFlags |= ENCODE_FIELD_SIG_MemberRefToken;
1610 if (pResolvedToken->pTypeSpec == NULL)
1612 fieldFlags &= ~ENCODE_METHOD_SIG_OwnerType;
1616 if (SigPointer(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec).IsPolyType(NULL) == hasNoVars)
1617 fieldFlags &= ~ENCODE_METHOD_SIG_OwnerType;
1622 _ASSERTE(!"Unexpected field token type!");
1629 pMT = pField->GetApproxEnclosingMethodTable();
1631 fieldFlags |= ENCODE_FIELD_SIG_IndexInsteadOfToken;
1637 pSigBuilder->AppendData(fieldFlags);
1639 if (fieldFlags & ENCODE_FIELD_SIG_OwnerType)
1641 if (fEncodeUsingResolvedTokenSpecStreams && pResolvedToken != NULL && pResolvedToken->pTypeSpec != NULL)
1643 _ASSERTE(pResolvedToken->cbTypeSpec > 0);
1645 DWORD moduleIndex = MODULE_INDEX_NONE;
1646 if ((IsReadyToRunCompilation() && pField->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope))
1648 moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope);
1651 SigParser sigParser(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
1652 CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex);
1656 ZapSig zapSig(pInfoModule, pEncodeModuleContext, ZapSig::NormalTokens,
1657 (EncodeModuleCallback)pfnEncodeModule, NULL);
1663 fSuccess = zapSig.GetSignatureForTypeHandle(pMT, pSigBuilder);
1668 if ((fieldFlags & ENCODE_FIELD_SIG_IndexInsteadOfToken) == 0)
1671 pSigBuilder->AppendData(RidFromToken(fieldToken));
1676 // Write field index
1679 DWORD fieldIndex = pMT->GetIndexForFieldDesc(pField);
1680 _ASSERTE(fieldIndex < DWORD(pMT->GetNumStaticFields() + pMT->GetNumIntroducedInstanceFields()));
1682 // have no token (e.g. it could be an array), encode slot number
1683 pSigBuilder->AppendData(fieldIndex);
1687 #endif // DACCESS_COMPILE