blob: 3f36483e81451b256ab48f1cce834b9824b3c185 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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
}
|