Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 72 additions & 50 deletions src/coreclr/interpreter/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7425,7 +7425,13 @@ bool InterpCompiler::IsRuntimeAsyncCall(const uint8_t* ip, OpcodePeepElement* pa

bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitTask(const uint8_t* ip, OpcodePeepElement* pattern, void** ppComputedInfo)
{
switch (*(ip + pattern[2].offsetIntoPeep - 1))
// IL pattern:
// # CALL | CALLVIRT at offset 0
// # LDC_I4_0 | LDC_I4_1
// CALLVIRT
// CALL

switch (*(ip + pattern[0].offsetIntoPeep - 1))
{
case CEE_LDC_I4_0:
m_currentContinuationContextHandling = ContinuationContextHandling::ContinueOnThreadPool;
Expand All @@ -7437,46 +7443,16 @@ bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitTask(const uint8_t* ip, Opc
return false;
}

uint32_t stLocVar = 0;
uint32_t ldlocaVar = 0;

switch (*(ip + pattern[0].offsetIntoPeep))
{
case CEE_STLOC_S:
stLocVar = (ip + pattern[0].offsetIntoPeep)[1];
break;
default:
// Must be STLOC
stLocVar = getU2LittleEndian(ip + pattern[0].offsetIntoPeep + 2);
break;
}

switch (*(ip + pattern[1].offsetIntoPeep))
{
case CEE_LDLOCA_S:
ldlocaVar = (ip + pattern[1].offsetIntoPeep)[1];
break;
default:
// Must be LDLOCA
ldlocaVar = getU2LittleEndian(ip + pattern[1].offsetIntoPeep + 2);
break;
}

if (ldlocaVar != stLocVar)
{
return false;
}

CORINFO_RESOLVED_TOKEN configureAwaitResolvedToken;
ResolveToken(getU4LittleEndian(ip + pattern[2].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &configureAwaitResolvedToken);
ResolveToken(getU4LittleEndian(ip + pattern[0].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &configureAwaitResolvedToken);
if (!m_compHnd->isIntrinsic(configureAwaitResolvedToken.hMethod) ||
GetNamedIntrinsic(m_compHnd, m_methodHnd, configureAwaitResolvedToken.hMethod) != NI_System_Threading_Tasks_Task_ConfigureAwait)
{
return false;
}

CORINFO_RESOLVED_TOKEN awaitResolvedToken;
ResolveToken(getU4LittleEndian(ip + pattern[3].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &awaitResolvedToken);
ResolveToken(getU4LittleEndian(ip + pattern[1].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &awaitResolvedToken);
if (!m_compHnd->isIntrinsic(awaitResolvedToken.hMethod) ||
GetNamedIntrinsic(m_compHnd, m_methodHnd, awaitResolvedToken.hMethod) != NI_System_Runtime_CompilerServices_AsyncHelpers_Await)
{
Expand All @@ -7488,17 +7464,13 @@ bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitTask(const uint8_t* ip, Opc

bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitValueTaskExactStLoc(const uint8_t* ip, OpcodePeepElement* pattern, void** ppComputedInfo)
{
switch (*(ip + pattern[1].offsetIntoPeep - 1))
{
case CEE_LDC_I4_0:
m_currentContinuationContextHandling = ContinuationContextHandling::ContinueOnThreadPool;
break;
case CEE_LDC_I4_1:
m_currentContinuationContextHandling = ContinuationContextHandling::ContinueOnCapturedContext;
break;
default:
return false;
}
// IL pattern:
// # CALL | CALLVIRT at offset 0
// # STLOC_0 | STLOC_1 | STLOC_2 | STLOC_3
// LDLOCA | LDLOCA_S
// # LDC_I4_0 | LDC_I4_1
// CALL
// CALL

uint32_t stLocVar = 0;
uint32_t ldlocaVar = 0;
Expand All @@ -7521,14 +7493,14 @@ bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitValueTaskExactStLoc(const u
return false;
}

switch (*(ip + pattern[1].offsetIntoPeep))
switch (*(ip + pattern[0].offsetIntoPeep))
{
case CEE_LDLOCA_S:
ldlocaVar = (ip + pattern[1].offsetIntoPeep)[1];
ldlocaVar = (ip + pattern[0].offsetIntoPeep)[1];
break;
default:
// Must be LDLOCA
ldlocaVar = getU2LittleEndian(ip + pattern[1].offsetIntoPeep + 2);
ldlocaVar = getU2LittleEndian(ip + pattern[0].offsetIntoPeep + 2);
break;
}

Expand All @@ -7537,6 +7509,18 @@ bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitValueTaskExactStLoc(const u
return false;
}

switch (*(ip + pattern[1].offsetIntoPeep - 1))
{
case CEE_LDC_I4_0:
m_currentContinuationContextHandling = ContinuationContextHandling::ContinueOnThreadPool;
break;
case CEE_LDC_I4_1:
m_currentContinuationContextHandling = ContinuationContextHandling::ContinueOnCapturedContext;
break;
default:
return false;
}

CORINFO_RESOLVED_TOKEN configureAwaitResolvedToken;
ResolveToken(getU4LittleEndian(ip + pattern[1].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &configureAwaitResolvedToken);
if (!m_compHnd->isIntrinsic(configureAwaitResolvedToken.hMethod) ||
Expand All @@ -7558,7 +7542,45 @@ bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitValueTaskExactStLoc(const u

bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitValueTask(const uint8_t* ip, OpcodePeepElement* pattern, void** ppComputedInfo)
{
switch (*(ip + pattern[0].offsetIntoPeep - 1))
// IL pattern:
// # CALL | CALLVIRT at offset 0
// STLOC | STLOC_S
// LDLOCA | LDLOCA_S
// # LDC_I4_0 | LDC_I4_1
// CALL
// CALL

uint32_t stLocVar = 0;
uint32_t ldlocaVar = 0;

switch (*(ip + pattern[0].offsetIntoPeep))
{
case CEE_STLOC_S:
stLocVar = (ip + pattern[0].offsetIntoPeep)[1];
break;
default:
// Must be STLOC
stLocVar = getU2LittleEndian(ip + pattern[0].offsetIntoPeep + 2);
break;
}

switch (*(ip + pattern[1].offsetIntoPeep))
{
case CEE_LDLOCA_S:
ldlocaVar = (ip + pattern[1].offsetIntoPeep)[1];
break;
default:
// Must be LDLOCA
ldlocaVar = getU2LittleEndian(ip + pattern[1].offsetIntoPeep + 2);
break;
}

if (ldlocaVar != stLocVar)
{
return false;
}

switch (*(ip + pattern[2].offsetIntoPeep - 1))
{
case CEE_LDC_I4_0:
m_currentContinuationContextHandling = ContinuationContextHandling::ContinueOnThreadPool;
Expand All @@ -7571,15 +7593,15 @@ bool InterpCompiler::IsRuntimeAsyncCallConfigureAwaitValueTask(const uint8_t* ip
}

CORINFO_RESOLVED_TOKEN configureAwaitResolvedToken;
ResolveToken(getU4LittleEndian(ip + pattern[0].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &configureAwaitResolvedToken);
ResolveToken(getU4LittleEndian(ip + pattern[2].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &configureAwaitResolvedToken);
if (!m_compHnd->isIntrinsic(configureAwaitResolvedToken.hMethod) ||
GetNamedIntrinsic(m_compHnd, m_methodHnd, configureAwaitResolvedToken.hMethod) != NI_System_Threading_Tasks_Task_ConfigureAwait)
{
return false;
}

CORINFO_RESOLVED_TOKEN awaitResolvedToken;
ResolveToken(getU4LittleEndian(ip + pattern[1].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &awaitResolvedToken);
ResolveToken(getU4LittleEndian(ip + pattern[3].offsetIntoPeep + 1), CORINFO_TOKENKIND_Method, &awaitResolvedToken);
if (!m_compHnd->isIntrinsic(awaitResolvedToken.hMethod) ||
GetNamedIntrinsic(m_compHnd, m_methodHnd, awaitResolvedToken.hMethod) != NI_System_Runtime_CompilerServices_AsyncHelpers_Await)
{
Expand Down
Loading