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.
5 // File: ILStubResolver.cpp
15 // returns pointer to IL code
16 BYTE* ILStubResolver::GetCodeInfo(unsigned* pCodeSize, unsigned* pStackSize, CorInfoOptions* pOptions, unsigned* pEHSize)
21 PRECONDITION(CheckPointer(pCodeSize));
22 PRECONDITION(CheckPointer(pStackSize));
23 PRECONDITION(CheckPointer(pOptions));
24 PRECONDITION(CheckPointer(pEHSize));
25 PRECONDITION(CheckPointer(m_pCompileTimeState));
26 POSTCONDITION(CheckPointer(RETVAL));
30 #ifndef DACCESS_COMPILE
31 CORINFO_METHOD_INFO methodInfo;
32 getMethodInfoILMethodHeaderHelper(&m_pCompileTimeState->m_ILHeader, &methodInfo);
34 *pCodeSize = methodInfo.ILCodeSize;
35 *pStackSize = methodInfo.maxStack;
36 *pOptions = methodInfo.options;
37 *pEHSize = methodInfo.EHcount;
39 RETURN methodInfo.ILCode;
40 #else // DACCESS_COMPILE
43 #endif // DACCESS_COMPILE
47 LPCUTF8 ILStubResolver::GetStubClassName(MethodDesc* pMD)
55 PRECONDITION(pMD->IsILStub());
59 if (pMD->GetDomain()->IsSharedDomain())
61 return "DomainNeutralILStubClass";
65 return "DomainBoundILStubClass";
69 LPCUTF8 ILStubResolver::GetStubMethodName()
81 case CLRToNativeInteropStub: return "IL_STUB_PInvoke";
82 case CLRToCOMInteropStub: return "IL_STUB_CLRtoCOM";
83 case CLRToWinRTInteropStub: return "IL_STUB_CLRtoWinRT";
84 case NativeToCLRInteropStub: return "IL_STUB_ReversePInvoke";
85 case COMToCLRInteropStub: return "IL_STUB_COMtoCLR";
86 case WinRTToCLRInteropStub: return "IL_STUB_WinRTtoCLR";
87 #ifdef FEATURE_ARRAYSTUB_AS_IL
88 case ArrayOpStub: return "IL_STUB_Array";
90 #ifdef FEATURE_STUBS_AS_IL
91 case MulticastDelegateStub: return "IL_STUB_MulticastDelegate_Invoke";
92 case UnboxingILStub: return "IL_STUB_UnboxingStub";
93 case InstantiatingStub: return "IL_STUB_InstantiatingStub";
94 case SecureDelegateStub: return "IL_STUB_SecureDelegate_Invoke";
97 UNREACHABLE_MSG("Unknown stub type");
101 void ILStubResolver::GetJitContext(SecurityControlFlags* pSecurityControlFlags,
102 TypeHandle* pTypeOwner)
107 PRECONDITION(CheckPointer(pSecurityControlFlags));
108 PRECONDITION(CheckPointer(pTypeOwner));
112 *pSecurityControlFlags = DynamicResolver::SkipVisibilityChecks;
113 *pTypeOwner = TypeHandle();
116 ChunkAllocator* ILStubResolver::GetJitMetaHeap()
118 LIMITED_METHOD_CONTRACT;
124 ILStubResolver::GetLocalSig()
126 STANDARD_VM_CONTRACT;
129 m_pCompileTimeState->m_ILHeader.LocalVarSig,
130 m_pCompileTimeState->m_ILHeader.cbLocalVarSig);
133 OBJECTHANDLE ILStubResolver::ConstructStringLiteral(mdToken token)
135 STANDARD_VM_CONTRACT;
140 BOOL ILStubResolver::IsValidStringRef(mdToken metaTok)
142 STANDARD_VM_CONTRACT;
147 void ILStubResolver::ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD)
149 STANDARD_VM_CONTRACT;
155 switch (TypeFromToken(token))
159 MethodDesc* pMD = m_pCompileTimeState->m_tokenLookupMap.LookupMethodDef(token);
162 *pTH = TypeHandle(pMD->GetMethodTable());
168 TypeHandle typeHnd = m_pCompileTimeState->m_tokenLookupMap.LookupTypeDef(token);
169 _ASSERTE(!typeHnd.IsNull());
176 FieldDesc* pFD = m_pCompileTimeState->m_tokenLookupMap.LookupFieldDef(token);
179 *pTH = TypeHandle(pFD->GetEnclosingMethodTable());
184 UNREACHABLE_MSG("unexpected metadata token type");
188 //---------------------------------------------------------------------------------------
191 ILStubResolver::ResolveSignature(
194 STANDARD_VM_CONTRACT;
195 CONSISTENCY_CHECK_MSG(token == TOKEN_ILSTUB_TARGET_SIG, "IL stubs do not support any other signature tokens!");
197 return m_pCompileTimeState->m_StubTargetMethodSig;
200 //---------------------------------------------------------------------------------------
203 ILStubResolver::ResolveSignatureForVarArg(
206 STANDARD_VM_CONTRACT;
211 //---------------------------------------------------------------------------------------
213 void ILStubResolver::GetEHInfo(unsigned EHnumber, CORINFO_EH_CLAUSE* clause)
218 PRECONDITION(CheckPointer(m_pCompileTimeState));
219 PRECONDITION(CheckPointer(m_pCompileTimeState->m_ILHeader.EH));
220 PRECONDITION(EHnumber < m_pCompileTimeState->m_ILHeader.EH->EHCount());
224 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehClause;
225 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
226 ehInfo = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)m_pCompileTimeState->m_ILHeader.EH->EHClause(EHnumber, &ehClause);
227 clause->Flags = (CORINFO_EH_CLAUSE_FLAGS)ehInfo->GetFlags();
228 clause->TryOffset = ehInfo->GetTryOffset();
229 clause->TryLength = ehInfo->GetTryLength();
230 clause->HandlerOffset = ehInfo->GetHandlerOffset();
231 clause->HandlerLength = ehInfo->GetHandlerLength();
232 clause->ClassToken = ehInfo->GetClassToken();
233 clause->FilterOffset = ehInfo->GetFilterOffset();
236 bool ILStubResolver::IsNativeToCLRInteropStub()
238 return (m_type == NativeToCLRInteropStub);
241 void ILStubResolver::SetStubType(ILStubType stubType)
243 LIMITED_METHOD_CONTRACT;
247 void ILStubResolver::SetStubMethodDesc(MethodDesc* pStubMD)
249 LIMITED_METHOD_CONTRACT;
250 m_pStubMD = PTR_MethodDesc(pStubMD);
253 void ILStubResolver::SetStubTargetMethodDesc(MethodDesc* pStubTargetMD)
255 LIMITED_METHOD_CONTRACT;
256 m_pStubTargetMD = PTR_MethodDesc(pStubTargetMD);
260 //---------------------------------------------------------------------------------------
263 ILStubResolver::SetStubTargetMethodSig(
264 PCCOR_SIGNATURE pStubTargetMethodSig,
265 DWORD cbStubTargetSigLength)
270 PRECONDITION(CheckPointer(m_pCompileTimeState));
274 NewHolder<BYTE> pNewSig = new BYTE[cbStubTargetSigLength];
276 memcpyNoGCRefs((void *)pNewSig, pStubTargetMethodSig, cbStubTargetSigLength);
278 m_pCompileTimeState->m_StubTargetMethodSig = SigPointer(pNewSig, cbStubTargetSigLength);
279 pNewSig.SuppressRelease();
282 //---------------------------------------------------------------------------------------
285 ILStubResolver::GetStubTargetMethodDesc()
287 LIMITED_METHOD_CONTRACT;
288 return m_pStubTargetMD;
291 MethodDesc* ILStubResolver::GetStubMethodDesc()
293 LIMITED_METHOD_CONTRACT;
297 ILStubResolver::ILStubResolver() :
298 m_pCompileTimeState(dac_cast<PTR_CompileTimeState>(ILNotYetGenerated)),
299 m_pStubMD(dac_cast<PTR_MethodDesc>(nullptr)),
300 m_pStubTargetMD(dac_cast<PTR_MethodDesc>(nullptr)),
304 LIMITED_METHOD_CONTRACT;
308 //---------------------------------------------------------------------------------------
310 COR_ILMETHOD_DECODER *
311 ILStubResolver::AllocGeneratedIL(
316 STANDARD_VM_CONTRACT;
318 #if !defined(DACCESS_COMPILE)
319 _ASSERTE(0 != cbCode);
321 NewHolder<BYTE> pNewILCodeBuffer = NULL;
322 NewHolder<BYTE> pNewLocalSig = NULL;
323 NewHolder<CompileTimeState> pNewCompileTimeState = NULL;
325 pNewCompileTimeState = (CompileTimeState *)new BYTE[sizeof(CompileTimeState)];
326 memset(pNewCompileTimeState, 0, sizeof(CompileTimeState));
328 pNewILCodeBuffer = new BYTE[cbCode];
332 pNewLocalSig = new BYTE[cbLocalSig];
335 COR_ILMETHOD_DECODER* pILHeader = &pNewCompileTimeState->m_ILHeader;
337 pILHeader->Flags = 0;
338 pILHeader->CodeSize = (DWORD)cbCode;
339 pILHeader->MaxStack = maxStack;
342 pILHeader->Code = pNewILCodeBuffer;
343 pILHeader->LocalVarSig = pNewLocalSig;
344 pILHeader->cbLocalVarSig = cbLocalSig;
347 LPVOID pPrevCompileTimeState =
349 FastInterlockExchangePointer(&m_pCompileTimeState, pNewCompileTimeState.GetValue());
350 CONSISTENCY_CHECK(ILNotYetGenerated == (UINT_PTR)pPrevCompileTimeState);
352 pNewLocalSig.SuppressRelease();
353 pNewILCodeBuffer.SuppressRelease();
354 pNewCompileTimeState.SuppressRelease();
358 #else // DACCESS_COMPILE
362 #endif // DACCESS_COMPILE
363 } // ILStubResolver::AllocGeneratedIL
365 //---------------------------------------------------------------------------------------
367 COR_ILMETHOD_DECODER* ILStubResolver::GetILHeader()
374 PRECONDITION(CheckPointer(m_pCompileTimeState));
378 return &m_pCompileTimeState->m_ILHeader;
381 COR_ILMETHOD_SECT_EH* ILStubResolver::AllocEHSect(size_t nClauses)
383 STANDARD_VM_CONTRACT;
387 size_t cbSize = sizeof(COR_ILMETHOD_SECT_EH)
388 - sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT)
389 + (nClauses * sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
390 m_pCompileTimeState->m_pEHSect = (COR_ILMETHOD_SECT_EH*) new BYTE[cbSize];
391 CONSISTENCY_CHECK(NULL == m_pCompileTimeState->m_ILHeader.EH);
392 m_pCompileTimeState->m_ILHeader.EH = m_pCompileTimeState->m_pEHSect;
393 return m_pCompileTimeState->m_pEHSect;
402 void ILStubResolver::FreeCompileTimeState()
412 if ((ILNotYetGenerated == dac_cast<TADDR>(m_pCompileTimeState)) ||
413 (ILGeneratedAndFreed == dac_cast<TADDR>(m_pCompileTimeState)))
418 ClearCompileTimeState(ILGeneratedAndFreed);
421 //---------------------------------------------------------------------------------------
424 ILStubResolver::ClearCompileTimeState(CompileTimeStatePtrSpecialValues newState)
435 // See allocations in AllocGeneratedIL and SetStubTargetMethodSig
438 COR_ILMETHOD_DECODER * pILHeader = &m_pCompileTimeState->m_ILHeader;
440 CONSISTENCY_CHECK(NULL != pILHeader->Code);
441 delete[] pILHeader->Code;
443 if (NULL != pILHeader->LocalVarSig)
445 delete[] pILHeader->LocalVarSig;
448 if (!m_pCompileTimeState->m_StubTargetMethodSig.IsNull())
450 delete[] m_pCompileTimeState->m_StubTargetMethodSig.GetPtr();
453 if (NULL != m_pCompileTimeState->m_pEHSect)
455 delete[] m_pCompileTimeState->m_pEHSect;
458 delete m_pCompileTimeState;
460 FastInterlockExchangePointer(&m_pCompileTimeState, dac_cast<PTR_CompileTimeState>((TADDR)newState));
461 } // ILStubResolver::ClearCompileTimeState
463 //---------------------------------------------------------------------------------------
466 ILStubResolver::SetTokenLookupMap(
467 TokenLookupMap * pMap)
472 PRECONDITION(CheckPointer(m_pCompileTimeState));
477 new (&m_pCompileTimeState->m_tokenLookupMap) TokenLookupMap(pMap);
480 bool ILStubResolver::IsCompiled()
482 LIMITED_METHOD_CONTRACT;
483 return (dac_cast<TADDR>(m_pCompileTimeState) == ILGeneratedAndFreed);
486 bool ILStubResolver::IsILGenerated()
488 return (dac_cast<TADDR>(m_pCompileTimeState) != ILNotYetGenerated);
491 void ILStubResolver::SetJitFlags(DWORD dwFlags)
493 LIMITED_METHOD_CONTRACT;
494 m_dwJitFlags = dwFlags;
497 DWORD ILStubResolver::GetJitFlags()
499 LIMITED_METHOD_CONTRACT;
504 void ILStubResolver::StubGenFailed(ILStubResolver* pResolver)
514 if ((ILNotYetGenerated == dac_cast<TADDR>(pResolver->m_pCompileTimeState)) ||
515 (ILGeneratedAndFreed == dac_cast<TADDR>(pResolver->m_pCompileTimeState)))
520 pResolver->ClearCompileTimeState(ILNotYetGenerated);