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_STUBS_AS_IL
87 case UnboxingILStub: return "IL_STUB_UnboxingStub";
88 case InstantiatingStub: return "IL_STUB_InstantiatingStub";
89 case SecureDelegateStub: return "IL_STUB_SecureDelegate_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 void ILStubResolver::SetStubType(ILStubType stubType)
238 LIMITED_METHOD_CONTRACT;
242 void ILStubResolver::SetStubMethodDesc(MethodDesc* pStubMD)
244 LIMITED_METHOD_CONTRACT;
245 m_pStubMD = PTR_MethodDesc(pStubMD);
248 void ILStubResolver::SetStubTargetMethodDesc(MethodDesc* pStubTargetMD)
250 LIMITED_METHOD_CONTRACT;
251 m_pStubTargetMD = PTR_MethodDesc(pStubTargetMD);
255 //---------------------------------------------------------------------------------------
258 ILStubResolver::SetStubTargetMethodSig(
259 PCCOR_SIGNATURE pStubTargetMethodSig,
260 DWORD cbStubTargetSigLength)
265 PRECONDITION(CheckPointer(m_pCompileTimeState));
269 NewArrayHolder<BYTE> pNewSig = new BYTE[cbStubTargetSigLength];
271 memcpyNoGCRefs((void *)pNewSig, pStubTargetMethodSig, cbStubTargetSigLength);
273 m_pCompileTimeState->m_StubTargetMethodSig = SigPointer(pNewSig, cbStubTargetSigLength);
274 pNewSig.SuppressRelease();
277 //---------------------------------------------------------------------------------------
280 ILStubResolver::GetStubTargetMethodDesc()
282 LIMITED_METHOD_CONTRACT;
283 return m_pStubTargetMD;
286 MethodDesc* ILStubResolver::GetStubMethodDesc()
288 LIMITED_METHOD_CONTRACT;
292 ILStubResolver::ILStubResolver() :
293 m_pCompileTimeState(dac_cast<PTR_CompileTimeState>(ILNotYetGenerated)),
294 m_pStubMD(dac_cast<PTR_MethodDesc>(nullptr)),
295 m_pStubTargetMD(dac_cast<PTR_MethodDesc>(nullptr)),
299 LIMITED_METHOD_CONTRACT;
303 //---------------------------------------------------------------------------------------
305 COR_ILMETHOD_DECODER *
306 ILStubResolver::AllocGeneratedIL(
311 STANDARD_VM_CONTRACT;
313 #if !defined(DACCESS_COMPILE)
314 _ASSERTE(0 != cbCode);
316 NewArrayHolder<BYTE> pNewILCodeBuffer = NULL;
317 NewArrayHolder<BYTE> pNewLocalSig = NULL;
318 NewArrayHolder<CompileTimeState> pNewCompileTimeState = NULL;
320 pNewCompileTimeState = (CompileTimeState *)new BYTE[sizeof(CompileTimeState)];
321 memset(pNewCompileTimeState, 0, sizeof(CompileTimeState));
323 pNewILCodeBuffer = new BYTE[cbCode];
327 pNewLocalSig = new BYTE[cbLocalSig];
330 COR_ILMETHOD_DECODER* pILHeader = &pNewCompileTimeState->m_ILHeader;
332 pILHeader->Flags = 0;
333 pILHeader->CodeSize = (DWORD)cbCode;
334 pILHeader->MaxStack = maxStack;
337 pILHeader->Code = pNewILCodeBuffer;
338 pILHeader->LocalVarSig = pNewLocalSig;
339 pILHeader->cbLocalVarSig = cbLocalSig;
342 LPVOID pPrevCompileTimeState =
344 FastInterlockExchangePointer(&m_pCompileTimeState, pNewCompileTimeState.GetValue());
345 CONSISTENCY_CHECK(ILNotYetGenerated == (UINT_PTR)pPrevCompileTimeState);
347 pNewLocalSig.SuppressRelease();
348 pNewILCodeBuffer.SuppressRelease();
349 pNewCompileTimeState.SuppressRelease();
353 #else // DACCESS_COMPILE
357 #endif // DACCESS_COMPILE
358 } // ILStubResolver::AllocGeneratedIL
360 //---------------------------------------------------------------------------------------
362 COR_ILMETHOD_DECODER* ILStubResolver::GetILHeader()
369 PRECONDITION(CheckPointer(m_pCompileTimeState));
373 return &m_pCompileTimeState->m_ILHeader;
376 COR_ILMETHOD_SECT_EH* ILStubResolver::AllocEHSect(size_t nClauses)
378 STANDARD_VM_CONTRACT;
382 size_t cbSize = sizeof(COR_ILMETHOD_SECT_EH)
383 - sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT)
384 + (nClauses * sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT));
385 m_pCompileTimeState->m_pEHSect = (COR_ILMETHOD_SECT_EH*) new BYTE[cbSize];
386 CONSISTENCY_CHECK(NULL == m_pCompileTimeState->m_ILHeader.EH);
387 m_pCompileTimeState->m_ILHeader.EH = m_pCompileTimeState->m_pEHSect;
388 return m_pCompileTimeState->m_pEHSect;
397 void ILStubResolver::FreeCompileTimeState()
407 if ((ILNotYetGenerated == dac_cast<TADDR>(m_pCompileTimeState)) ||
408 (ILGeneratedAndFreed == dac_cast<TADDR>(m_pCompileTimeState)))
413 ClearCompileTimeState(ILGeneratedAndFreed);
416 //---------------------------------------------------------------------------------------
419 ILStubResolver::ClearCompileTimeState(CompileTimeStatePtrSpecialValues newState)
430 // See allocations in AllocGeneratedIL and SetStubTargetMethodSig
433 COR_ILMETHOD_DECODER * pILHeader = &m_pCompileTimeState->m_ILHeader;
435 CONSISTENCY_CHECK(NULL != pILHeader->Code);
436 delete[] pILHeader->Code;
438 if (NULL != pILHeader->LocalVarSig)
440 delete[] pILHeader->LocalVarSig;
443 if (!m_pCompileTimeState->m_StubTargetMethodSig.IsNull())
445 delete[] m_pCompileTimeState->m_StubTargetMethodSig.GetPtr();
448 if (NULL != m_pCompileTimeState->m_pEHSect)
450 delete[] m_pCompileTimeState->m_pEHSect;
453 delete m_pCompileTimeState;
455 FastInterlockExchangePointer(&m_pCompileTimeState, dac_cast<PTR_CompileTimeState>((TADDR)newState));
456 } // ILStubResolver::ClearCompileTimeState
458 //---------------------------------------------------------------------------------------
461 ILStubResolver::SetTokenLookupMap(
462 TokenLookupMap * pMap)
467 PRECONDITION(CheckPointer(m_pCompileTimeState));
472 new (&m_pCompileTimeState->m_tokenLookupMap) TokenLookupMap(pMap);
475 bool ILStubResolver::IsCompiled()
477 LIMITED_METHOD_CONTRACT;
478 return (dac_cast<TADDR>(m_pCompileTimeState) == ILGeneratedAndFreed);
481 bool ILStubResolver::IsILGenerated()
483 return (dac_cast<TADDR>(m_pCompileTimeState) != ILNotYetGenerated);
486 void ILStubResolver::SetJitFlags(CORJIT_FLAGS jitFlags)
488 LIMITED_METHOD_CONTRACT;
489 m_jitFlags = jitFlags;
492 CORJIT_FLAGS ILStubResolver::GetJitFlags()
494 LIMITED_METHOD_CONTRACT;
499 void ILStubResolver::StubGenFailed(ILStubResolver* pResolver)
509 if ((ILNotYetGenerated == dac_cast<TADDR>(pResolver->m_pCompileTimeState)) ||
510 (ILGeneratedAndFreed == dac_cast<TADDR>(pResolver->m_pCompileTimeState)))
515 pResolver->ClearCompileTimeState(ILNotYetGenerated);