Skip to content

Commit

Permalink
Import isinst/castclass Nullable as underlying type (#87241)
Browse files Browse the repository at this point in the history
* Import isinst Nullable as underlying type

* IL test coverage for castclass
  • Loading branch information
huoyaoyuan committed Jun 21, 2023
1 parent 11dcb89 commit 74196a0
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/coreclr/jit/importer.cpp
Expand Up @@ -5435,6 +5435,23 @@ GenTree* Compiler::impCastClassOrIsInstToTree(
bool shouldExpandInline = true;
bool isClassExact = impIsClassExact(pResolvedToken->hClass);

// ECMA-335 III.4.3: If typeTok is a nullable type, Nullable<T>, it is interpreted as "boxed" T
// We can convert constant-ish tokens of nullable to its underlying type.
// However, when the type is shared generic parameter like Nullable<Struct<__Canon>>, the actual type will require
// runtime lookup. It's too complex to add another level of indirection in op2, fallback to the cast helper instead.
if (isClassExact && !(info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST))
{
CORINFO_CLASS_HANDLE hClass = info.compCompHnd->getTypeForBox(pResolvedToken->hClass);

if (hClass != pResolvedToken->hClass)
{
bool runtimeLookup;
pResolvedToken->hClass = hClass;
op2 = impTokenToHandle(pResolvedToken, &runtimeLookup);
assert(!runtimeLookup);
}
}

// Profitability check.
//
// Don't bother with inline expansion when jit is trying to generate code quickly
Expand Down
60 changes: 60 additions & 0 deletions src/tests/JIT/opt/Casts/castclass_valuetype.il
@@ -0,0 +1,60 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.


.assembly extern mscorlib { auto }
.assembly extern xunit.core {}
.assembly extern System.Console { auto }
.assembly extern System.Runtime { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) }

.assembly 'castclass_valuetype' { }

.class public auto Program extends [System.Runtime]System.Object
{
.method public hidebysig static int32 Main() cil managed
{
.custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = (
01 00 00 00
)
.entrypoint
.maxstack 8

.try
{
// castclass valuetype
ldc.i4 1234
box int32
castclass int32
unbox int32
call instance string [System.Runtime]System.Int32::ToString()
call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String)

// castclass nullable
ldc.i4 1234
box int32
castclass valuetype [System.Runtime]System.Nullable`1<int32>
unbox int32
call instance string [System.Runtime]System.Int32::ToString()
call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String)

leave.s SUCCESS
}
catch [System.Runtime]System.Object
{
pop
leave.s FAIL
}

SUCCESS:
ldstr "SUCCESS"
call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String)
ldc.i4 100
ret

FAIL:
ldstr "FAILED"
call void [System.Console]System.Console::WriteLine(class [System.Runtime]System.String)
ldc.i4 0
ret
}
}
11 changes: 11 additions & 0 deletions src/tests/JIT/opt/Casts/castclass_valuetype.ilproj
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.IL">
<PropertyGroup>
<CLRTestPriority>1</CLRTestPriority>
</PropertyGroup>
<PropertyGroup>
<DebugType>PdbOnly</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="castclass_valuetype.il" />
</ItemGroup>
</Project>

0 comments on commit 74196a0

Please sign in to comment.