Fix importing of calls with explicit `this`. (#35385)
authorEugene Rozenfeld <erozen@microsoft.com>
Fri, 24 Apr 2020 18:46:32 +0000 (11:46 -0700)
committerGitHub <noreply@github.com>
Fri, 24 Apr 2020 18:46:32 +0000 (11:46 -0700)
When signature calling convention has `CORINFO_CALLCONV_EXPLICITTHIS`
set `this` argument is explicitly included in the argument list.
The importer wasn't taking that into account and was trying to pop
an implicit `this`, which resulted in `BADCODE("stack underflow")`
from `impPopStack` and `System.InvalidProgramException`.

Fixes #35384

src/coreclr/src/jit/importer.cpp
src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_35384/GitHub_35384.il [new file with mode: 0644]
src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_35384/GitHub_35384.ilproj [new file with mode: 0644]

index 155113b..973541e 100644 (file)
@@ -8261,7 +8261,8 @@ var_types Compiler::impImportCall(OPCODE                  opcode,
     //-------------------------------------------------------------------------
     // The "this" pointer
 
-    if (!(mflags & CORINFO_FLG_STATIC) && !((opcode == CEE_NEWOBJ) && (newobjThis == nullptr)))
+    if (((mflags & CORINFO_FLG_STATIC) == 0) && ((sig->callConv & CORINFO_CALLCONV_EXPLICITTHIS) == 0) &&
+        !((opcode == CEE_NEWOBJ) && (newobjThis == nullptr)))
     {
         GenTree* obj;
 
diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_35384/GitHub_35384.il b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_35384/GitHub_35384.il
new file mode 100644 (file)
index 0000000..46b1e97
--- /dev/null
@@ -0,0 +1,50 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// This tests a calli with explicit this in the signature
+
+.assembly extern System.Runtime {}
+.assembly GitHub_35384 {}
+
+.class private sequential ansi sealed beforefieldinit Struct
+       extends [System.Runtime]System.ValueType
+{
+  .field public int32 a
+
+  .method public hidebysig instance string 
+          InstanceMethod() cil managed noinlining
+  {
+    .maxstack  1
+    ldstr      "Instance method"
+    ret
+  } // end of method Struct::InstanceMethod
+
+} // end of class Struct
+
+.class public auto beforefieldinit Program
+       extends [System.Runtime]System.Object
+{
+  .method private hidebysig static string 
+          ValueTypeExplicitThisInstanceMethodCalli() cil managed noinlining
+  {
+    .maxstack  2
+    .locals init (valuetype Struct V_0)
+    ldloca.s   V_0
+    initobj    Struct
+    ldloca.s   V_0
+    ldftn      instance string Struct::InstanceMethod()
+    calli      explicit instance string(valuetype Struct&)
+    ret
+  } // end of method Program::ValueTypeExplicitThisInstanceMethodCalli
+  
+  .method private hidebysig static int32 Main() cil managed
+  {
+    .entrypoint
+    .maxstack 1
+    call       string Program::ValueTypeExplicitThisInstanceMethodCalli()
+    pop
+    ldc.i4 100
+    ret
+  } // end of method Program::Main
+} // end of class Program
diff --git a/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_35384/GitHub_35384.ilproj b/src/coreclr/tests/src/JIT/Regression/JitBlue/GitHub_35384/GitHub_35384.ilproj
new file mode 100644 (file)
index 0000000..e7c67cc
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk.IL">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>None</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).il" />
+  </ItemGroup>
+</Project>