Add test coverage for Rank 1 multidimensional arrays (#11034)
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>
Wed, 19 Apr 2017 19:01:57 +0000 (12:01 -0700)
committerGitHub <noreply@github.com>
Wed, 19 Apr 2017 19:01:57 +0000 (12:01 -0700)
These have some weird behaviors worth covering.

tests/src/baseservices/multidimmarray/rank1array.il [new file with mode: 0644]
tests/src/baseservices/multidimmarray/rank1array.ilproj [new file with mode: 0644]

diff --git a/tests/src/baseservices/multidimmarray/rank1array.il b/tests/src/baseservices/multidimmarray/rank1array.il
new file mode 100644 (file)
index 0000000..3f36483
--- /dev/null
@@ -0,0 +1,160 @@
+// 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.
+
+// Tests that SzArray is castable to multidimensional array of rank 1 with zero lower bounds
+// and that the MdArray methods can operate on such `this`.
+// We cast an SzArray to MdArray, call methods on it, and validate the SzArray was updated
+// at the expected memory locations.
+
+.assembly extern mscorlib { }
+
+.assembly rank1array
+{
+}
+
+.module rank1array.exe
+.subsystem 0x0003
+.corflags 0x00000001
+
+.method public hidebysig static int32 Main () cil managed
+{
+    .locals init(
+        [0] int32[] szArray,
+        [1] int32[0...] mdArray
+    )
+
+    .maxstack 8
+    .entrypoint
+
+    ldc.i4.2
+    newarr int32
+    stloc.0
+
+    // SzArray is castable to MdArray rank 1 with zero lower bounds
+    ldloc.0
+    castclass int32[0...]
+    stloc.1
+
+    ldloc.1
+    ldc.i4.0
+    ldc.i4 0x4d2
+    call instance void int32[0...]::Set(int32, int32)
+
+    // The call to Set had better updated the memory location we expect
+    ldloc.0
+    ldc.i4.0
+    ldelem.i4
+    ldc.i4 0x4d2
+    ceq
+    brtrue SetOK
+    ldc.i4.1
+    ret
+
+SetOK:
+    ldloc.1
+    ldc.i4.0
+    call instance int32 int32[0...]::Get(int32)
+    ldc.i4 0x4d2
+    ceq
+    brtrue GetOK
+    ldc.i4.2
+    ret
+
+GetOK:
+    ldloc.1
+    ldc.i4.1
+    call instance int32& int32[0...]::Address(int32)
+    ldc.i4 42
+    stind.i4
+
+    // The call to Address had better given us the memory location we expect
+    ldloc.0
+    ldc.i4.1
+    ldelem.i4
+    ldc.i4 42
+    ceq
+    brtrue AddressOK
+    ldc.i4.3
+    ret
+
+AddressOK:
+
+    // We can also cast through type-size-equivalence
+    ldc.i4.0
+    newarr int32
+    isinst uint32[0...]
+    brtrue SizeEquivalenceOK
+    ldc.i4.4
+    ret
+
+SizeEquivalenceOK:
+
+    // We follow all the size equivalence rules though
+    ldc.i4.0
+    newarr float32
+    isinst uint32[0...]
+    brfalse SizeEquivalenceNegativeOK
+    ldc.i4.5
+    ret
+
+SizeEquivalenceNegativeOK:
+
+    // String -> object casts
+    ldc.i4.0
+    newarr string
+    isinst object[0...]
+    brtrue StringObjectCastOK
+    ldc.i4.6
+    ret
+
+StringObjectCastOK:
+
+    // Object -> string negative cast
+    ldc.i4.0
+    newarr object
+    isinst string[0...]
+    brfalse ObjectStringNegativeOK
+    ldc.i4.7
+    ret
+
+ObjectStringNegativeOK:
+
+    // MdArray of rank 1 is also castable to SzArray
+    ldc.i4.0
+    newobj instance void int32[0...]::.ctor(int32)
+    isinst int32[]
+    brtrue MdSzArrayOK
+    ldc.i4.8
+    ret
+
+MdSzArrayOK:
+
+    // "newobj instance void int32[0...]::.ctor(int32)" actually gives you int[]
+    ldc.i4.1
+    newobj instance void int32[0...]::.ctor(int32)
+    call instance class [mscorlib]System.Type class [mscorlib]System.Object::GetType()
+    ldtoken int32[]
+    call class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+    ceq
+    brtrue Int32ArrayRank1IsInt32SzArray
+    ldc.i4 9
+    ret
+
+Int32ArrayRank1IsInt32SzArray:
+
+    // int32[] and int32[0..] are still different types though
+    ldtoken int32[]
+    call class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+    ldtoken int32[0...]
+    call class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+    ceq
+    brfalse DifferentTypes
+    ldc.i4 10
+    ret
+
+DifferentTypes:
+
+    ldc.i4 100
+    ret
+}
diff --git a/tests/src/baseservices/multidimmarray/rank1array.ilproj b/tests/src/baseservices/multidimmarray/rank1array.ilproj
new file mode 100644 (file)
index 0000000..6679689
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <AssemblyName>rank1array</AssemblyName>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{405DB174-DAB1-4095-BC2D-B64E38E94B8B}</ProjectGuid>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <OutputType>Exe</OutputType>
+    <CLRTestKind>BuildAndRun</CLRTestKind>
+    <CLRTestPriority>0</CLRTestPriority>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Include="rank1array.il" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>