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());
62 LPCUTF8 ILStubResolver::GetStubMethodName()
74 case CLRToNativeInteropStub: return "IL_STUB_PInvoke";
75 case CLRToCOMInteropStub: return "IL_STUB_CLRtoCOM";
76 case CLRToWinRTInteropStub: return "IL_STUB_CLRtoWinRT";
77 case NativeToCLRInteropStub: return "IL_STUB_ReversePInvoke";
78 case COMToCLRInteropStub: return "IL_STUB_COMtoCLR";
79 case WinRTToCLRInteropStub: return "IL_STUB_WinRTtoCLR";
80 #ifdef FEATURE_ARRAYSTUB_AS_IL
81 case ArrayOpStub: return "IL_STUB_Array";
83 #ifdef FEATURE_MULTICASTSTUB_AS_IL
84 case MulticastDelegateStub: return "IL_STUB_MulticastDelegate_Invoke";
86 #ifdef FEATURE_INSTANTIATINGSTUB_AS_IL
87 case UnboxingILStub: return "IL_STUB_UnboxingStub";
88 case InstantiatingStub: return "IL_STUB_InstantiatingStub";
90 case WrapperDelegateStub: return "IL_STUB_WrapperDelegate_Invoke";
92 UNREACHABLE_MSG("Unknown stub type");
96 void ILStubResolver::GetJitContext(SecurityControlFlags* pSecurityControlFlags,
97 TypeHandle* pTypeOwner)
102 PRECONDITION(CheckPointer(pSecurityControlFlags));
103 PRECONDITION(CheckPointer(pTypeOwner));
107 *pSecurityControlFlags = DynamicResolver::SkipVisibilityChecks;
108 *pTypeOwner = TypeHandle();
111 ChunkAllocator* ILStubResolver::GetJitMetaHeap()
113 LIMITED_METHOD_CONTRACT;
119 ILStubResolver::GetLocalSig()
121 STANDARD_VM_CONTRACT;
124 m_pCompileTimeState->m_ILHeader.LocalVarSig,
125 m_pCompileTimeState->m_ILHeader.cbLocalVarSig);
128 OBJECTHANDLE ILStubResolver::ConstructStringLiteral(mdToken token)
130 STANDARD_VM_CONTRACT;
135 BOOL ILStubResolver::IsValidStringRef(mdToken metaTok)
137 STANDARD_VM_CONTRACT;
142 void ILStubResolver::ResolveToken(mdToken token, TypeHandle * pTH, MethodDesc ** ppMD, FieldDesc ** ppFD)
144 STANDARD_VM_CONTRACT;
150 switch (TypeFromToken(token))
154 MethodDesc* pMD = m_pCompileTimeState->m_tokenLookupMap.LookupMethodDef(token);
157 *pTH = TypeHandle(pMD->GetMethodTable());
163 TypeHandle typeHnd = m_pCompileTimeState->m_tokenLookupMap.LookupTypeDef(token);
164 _ASSERTE(!typeHnd.IsNull());
171 FieldDesc* pFD = m_pCompileTimeState->m_tokenLookupMap.LookupFieldDef(token);
174 *pTH = TypeHandle(pFD->GetEnclosingMethodTable());
179 UNREACHABLE_MSG("unexpected metadata token type");
183 //---------------------------------------------------------------------------------------
186 ILStubResolver::ResolveSignature(
189 STANDARD_VM_CONTRACT;
190 CONSISTENCY_CHECK_MSG(token == TOKEN_ILSTUB_TARGET_SIG, "IL stubs do not support any other signature tokens!");
192 return m_pCompileTimeState->m_StubTargetMethodSig;
195 //---------------------------------------------------------------------------------------
198 ILStubResolver::ResolveSignatureForVarArg(
201 STANDARD_VM_CONTRACT;
206 //---------------------------------------------------------------------------------------
208 void ILStubResolver::GetEHInfo(unsigned EHnumber, CORINFO_EH_CLAUSE* clause)
213 PRECONDITION(CheckPointer(m_pCompileTimeState));
214 PRECONDITION(CheckPointer(m_pCompileTimeState->m_ILHeader.EH));
215 PRECONDITION(EHnumber < m_pCompileTimeState->m_ILHeader.EH->EHCount());
219 COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehClause;
220 const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
221 ehInfo = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)m_pCompileTimeState->m_ILHeader.EH->EHClause(EHnumber, &ehClause);
222 clause->Flags = (CORINFO_EH_CLAUSE_FLAGS)ehInfo->GetFlags();
223 clause->TryOffset = ehInfo->GetTryOffset();
224 clause->TryLength = ehInfo->GetTryLength();
225 clause->HandlerOffset = ehInfo->GetHandlerOffset();
226 clause->HandlerLength = ehInfo->GetHandlerLength();
227 clause->ClassToken = ehInfo->GetClassToken();
228 clause->FilterOffset = ehInfo->GetFilterOffset();
231 bool ILStubResolver::IsNativeToCLRInteropStub()
233 return (m_type == NativeToCLRInteropStub);
236 bool ILStubResolver::IsCLRToNativeInteropStub()
238 return (m_type == CLRToNativeInteropStub);
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 NewArrayHolder<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 NewArrayHolder<BYTE> pNewILCodeBuffer = NULL;
322 NewArrayHolder<BYTE> pNewLocalSig = NULL;
323 NewArrayHolder<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;
401 void ILStubResolver::FreeCompileTimeState()
411 if ((ILNotYetGenerated == dac_cast<TADDR>(m_pCompileTimeState)) ||
412 (ILGeneratedAndFreed == dac_cast<TADDR>(m_pCompileTimeState)))
417 ClearCompileTimeState(ILGeneratedAndFreed);
420 //---------------------------------------------------------------------------------------
423 ILStubResolver::ClearCompileTimeState(CompileTimeStatePtrSpecialValues newState)
434 // See allocations in AllocGeneratedIL and SetStubTargetMethodSig
437 COR_ILMETHOD_DECODER * pILHeader = &m_pCompileTimeState->m_ILHeader;
439 CONSISTENCY_CHECK(NULL != pILHeader->Code);
440 delete[] pILHeader->Code;
442 if (NULL != pILHeader->LocalVarSig)
444 delete[] pILHeader->LocalVarSig;
447 if (!m_pCompileTimeState->m_StubTargetMethodSig.IsNull())
449 delete[] m_pCompileTimeState->m_StubTargetMethodSig.GetPtr();
452 if (NULL != m_pCompileTimeState->m_pEHSect)
454 delete[] m_pCompileTimeState->m_pEHSect;
457 delete m_pCompileTimeState;
459 FastInterlockExchangePointer(&m_pCompileTimeState, dac_cast<PTR_CompileTimeState>((TADDR)newState));
460 } // ILStubResolver::ClearCompileTimeState
462 //---------------------------------------------------------------------------------------
465 ILStubResolver::SetTokenLookupMap(
466 TokenLookupMap * pMap)
471 PRECONDITION(CheckPointer(m_pCompileTimeState));
476 new (&m_pCompileTimeState->m_tokenLookupMap) TokenLookupMap(pMap);
479 bool ILStubResolver::IsCompiled()
481 LIMITED_METHOD_CONTRACT;
482 return (dac_cast<TADDR>(m_pCompileTimeState) == ILGeneratedAndFreed);
485 bool ILStubResolver::IsILGenerated()
487 return (dac_cast<TADDR>(m_pCompileTimeState) != ILNotYetGenerated);
490 void ILStubResolver::SetJitFlags(CORJIT_FLAGS jitFlags)
492 LIMITED_METHOD_CONTRACT;
493 m_jitFlags = jitFlags;
496 CORJIT_FLAGS ILStubResolver::GetJitFlags()
498 LIMITED_METHOD_CONTRACT;
503 void ILStubResolver::StubGenFailed(ILStubResolver* pResolver)
513 if ((ILNotYetGenerated == dac_cast<TADDR>(pResolver->m_pCompileTimeState)) ||
514 (ILGeneratedAndFreed == dac_cast<TADDR>(pResolver->m_pCompileTimeState)))
519 pResolver->ClearCompileTimeState(ILNotYetGenerated);