Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ if(FEATURE_OBJCMARSHAL)
add_compile_definitions(FEATURE_OBJCMARSHAL)
endif()

# add_compile_definitions(FEATURE_RUNTIME_ASYNC)
add_compile_definitions(FEATURE_RUNTIME_ASYNC)

add_compile_definitions($<${FEATURE_JAVAMARSHAL}:FEATURE_JAVAMARSHAL>)

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,9 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zba, W("EnableRiscV64
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zbb, W("EnableRiscV64Zbb"), 1, "Allows RiscV64 Zbb hardware intrinsics to be disabled")
#endif

// Runtime-async
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_RuntimeAsync, W("RuntimeAsync"), 0, "Enable support for async methods")

///
/// Uncategorized
///
Expand Down
89 changes: 45 additions & 44 deletions src/coreclr/vm/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2318,65 +2318,66 @@ MethodReturnKind ClassifyMethodReturnKind(SigPointer sig, Module* pModule, ULONG
{
// Without FEATURE_RUNTIME_ASYNC every declared method is classified as a NormalMethod.
// Thus code that handles runtime async scenarios becomes unreachable.
#ifdef FEATURE_RUNTIME_ASYNC
PCCOR_SIGNATURE initialSig = sig.GetPtr();
uint32_t data;
IfFailThrow(sig.GetCallingConvInfo(&data));
if (data & IMAGE_CEE_CS_CALLCONV_GENERIC)
if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RuntimeAsync) != 0)
{
// Skip over generic argument count
IfFailThrow(sig.GetData(&data));
}

// skip argument count
IfFailThrow(sig.GetData(&data));

// now look at return type
// NOTE: this will skip modifiers
CorElementType elemType;
IfFailThrow(sig.GetElemType(&elemType));
PCCOR_SIGNATURE initialSig = sig.GetPtr();
uint32_t data;
IfFailThrow(sig.GetCallingConvInfo(&data));
if (data & IMAGE_CEE_CS_CALLCONV_GENERIC)
{
// Skip over generic argument count
IfFailThrow(sig.GetData(&data));
}

// can't reason about ELEMENT_TYPE_INTERNAL, but should not see it in metadata
if (elemType == ELEMENT_TYPE_INTERNAL)
ThrowHR(COR_E_BADIMAGEFORMAT);
// skip argument count
IfFailThrow(sig.GetData(&data));

*offsetOfAsyncDetails = (ULONG)(sig.GetPtr() - initialSig) - 1;
LPCSTR name, _namespace;
mdToken tk;
if (elemType == ELEMENT_TYPE_GENERICINST)
{
// now look at return type
// NOTE: this will skip modifiers
CorElementType elemType;
IfFailThrow(sig.GetElemType(&elemType));

// can't reason about ELEMENT_TYPE_INTERNAL, but should not see it in metadata
if (elemType == ELEMENT_TYPE_INTERNAL)
ThrowHR(COR_E_BADIMAGEFORMAT);

*isValueTask = (elemType == ELEMENT_TYPE_VALUETYPE);
IfFailThrow(sig.GetToken(&tk));
IfFailThrow(sig.GetData(&data));
if (data == 1)
*offsetOfAsyncDetails = (ULONG)(sig.GetPtr() - initialSig) - 1;
LPCSTR name, _namespace;
mdToken tk;
if (elemType == ELEMENT_TYPE_GENERICINST)
{
// This might be System.Threading.Tasks.Task`1
GetNameOfTypeDefOrRef(pModule, tk, &name, &_namespace);
if ((strcmp(name, *isValueTask ? "ValueTask`1" : "Task`1") == 0) && strcmp(_namespace, "System.Threading.Tasks") == 0)
IfFailThrow(sig.GetElemType(&elemType));
// can't reason about ELEMENT_TYPE_INTERNAL, but should not see it in metadata
if (elemType == ELEMENT_TYPE_INTERNAL)
ThrowHR(COR_E_BADIMAGEFORMAT);

*isValueTask = (elemType == ELEMENT_TYPE_VALUETYPE);
IfFailThrow(sig.GetToken(&tk));
IfFailThrow(sig.GetData(&data));
if (data == 1)
{
if (IsTypeDefOrRefImplementedInSystemModule(pModule, tk))
return MethodReturnKind::GenericTaskReturningMethod;
// This might be System.Threading.Tasks.Task`1
GetNameOfTypeDefOrRef(pModule, tk, &name, &_namespace);
if ((strcmp(name, *isValueTask ? "ValueTask`1" : "Task`1") == 0) && strcmp(_namespace, "System.Threading.Tasks") == 0)
{
if (IsTypeDefOrRefImplementedInSystemModule(pModule, tk))
return MethodReturnKind::GenericTaskReturningMethod;
}
}
}
}
else if ((elemType == ELEMENT_TYPE_CLASS) || (elemType == ELEMENT_TYPE_VALUETYPE))
{
IfFailThrow(sig.GetToken(&tk));
*isValueTask = (elemType == ELEMENT_TYPE_VALUETYPE);
// This might be System.Threading.Tasks.Task or ValueTask
GetNameOfTypeDefOrRef(pModule, tk, &name, &_namespace);
if ((strcmp(name, *isValueTask ? "ValueTask" : "Task") == 0) && strcmp(_namespace, "System.Threading.Tasks") == 0)
else if ((elemType == ELEMENT_TYPE_CLASS) || (elemType == ELEMENT_TYPE_VALUETYPE))
{
if (IsTypeDefOrRefImplementedInSystemModule(pModule, tk))
return MethodReturnKind::NonGenericTaskReturningMethod;
IfFailThrow(sig.GetToken(&tk));
*isValueTask = (elemType == ELEMENT_TYPE_VALUETYPE);
// This might be System.Threading.Tasks.Task or ValueTask
GetNameOfTypeDefOrRef(pModule, tk, &name, &_namespace);
if ((strcmp(name, *isValueTask ? "ValueTask" : "Task") == 0) && strcmp(_namespace, "System.Threading.Tasks") == 0)
{
if (IsTypeDefOrRefImplementedInSystemModule(pModule, tk))
return MethodReturnKind::NonGenericTaskReturningMethod;
}
}
}
#endif // FEATURE_RUNTIME_ASYNC

return MethodReturnKind::NormalMethod;
}
Expand Down
11 changes: 7 additions & 4 deletions src/coreclr/vm/methodtablebuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2682,10 +2682,13 @@ MethodTableBuilder::EnumerateClassMethods()
BuildMethodTableThrowException(IDS_CLASSLOAD_TOO_MANY_METHODS);

bmtMethod->m_cMaxDeclaredMethods = (SLOT_INDEX)cMethAndGaps;
#ifdef FEATURE_RUNTIME_ASYNC
// TODO: (async) the index is uint16 and can potentially overflow. This needs to be more robust.
bmtMethod->m_cMaxDeclaredMethods *= 2;
#endif

if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RuntimeAsync) != 0)
{
// TODO: (async) the index is uint16 and can potentially overflow. This needs to be more robust.
bmtMethod->m_cMaxDeclaredMethods *= 2;
}

bmtMethod->m_cDeclaredMethods = 0;
bmtMethod->m_rgDeclaredMethods = new (GetStackingAllocator())
bmtMDMethod *[bmtMethod->m_cMaxDeclaredMethods];
Expand Down
Loading