7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 /*
26 * @test
27 * @enablePreview
28 * @run testng TestDereferencePath
29 */
30
31 import java.lang.foreign.Arena;
32 import java.lang.foreign.MemoryLayout;
33 import java.lang.foreign.MemoryLayout.PathElement;
34 import java.lang.foreign.MemorySegment;
35
36 import java.lang.foreign.ValueLayout;
37
38 import org.testng.annotations.*;
39
40 import java.lang.invoke.VarHandle;
41 import static org.testng.Assert.*;
42
43 public class TestDereferencePath {
44
45 static final MemoryLayout C = MemoryLayout.structLayout(
46 ValueLayout.JAVA_INT.withName("x")
47 );
56 .withTargetLayout(B)
57 );
58
59 static final VarHandle abcx = A.varHandle(
60 PathElement.groupElement("b"), PathElement.dereferenceElement(),
61 PathElement.groupElement("c"), PathElement.dereferenceElement(),
62 PathElement.groupElement("x"));
63
64 @Test
65 public void testSingle() {
66 try (Arena arena = Arena.ofConfined()) {
67 // init structs
68 MemorySegment a = arena.allocate(A);
69 MemorySegment b = arena.allocate(B);
70 MemorySegment c = arena.allocate(C);
71 // init struct fields
72 a.set(ValueLayout.ADDRESS, 0, b);
73 b.set(ValueLayout.ADDRESS, 0, c);
74 c.set(ValueLayout.JAVA_INT, 0, 42);
75 // dereference
76 int val = (int) abcx.get(a);
77 assertEquals(val, 42);
78 }
79 }
80
81 static final MemoryLayout B_MULTI = MemoryLayout.structLayout(
82 ValueLayout.ADDRESS.withName("cs")
83 .withTargetLayout(MemoryLayout.sequenceLayout(2, C))
84 );
85
86 static final MemoryLayout A_MULTI = MemoryLayout.structLayout(
87 ValueLayout.ADDRESS.withName("bs")
88 .withTargetLayout(MemoryLayout.sequenceLayout(2, B_MULTI))
89 );
90
91 static final VarHandle abcx_multi = A_MULTI.varHandle(
92 PathElement.groupElement("bs"), PathElement.dereferenceElement(), PathElement.sequenceElement(),
93 PathElement.groupElement("cs"), PathElement.dereferenceElement(), PathElement.sequenceElement(),
94 PathElement.groupElement("x"));
95
96 @Test
97 public void testMulti() {
98 try (Arena arena = Arena.ofConfined()) {
99 // init structs
100 MemorySegment a = arena.allocate(A);
101 MemorySegment b = arena.allocateArray(B, 2);
102 MemorySegment c = arena.allocateArray(C, 4);
103 // init struct fields
104 a.set(ValueLayout.ADDRESS, 0, b);
105 b.set(ValueLayout.ADDRESS, 0, c);
106 b.setAtIndex(ValueLayout.ADDRESS, 1, c.asSlice(C.byteSize() * 2));
107 c.setAtIndex(ValueLayout.JAVA_INT, 0, 1);
108 c.setAtIndex(ValueLayout.JAVA_INT, 1, 2);
109 c.setAtIndex(ValueLayout.JAVA_INT, 2, 3);
110 c.setAtIndex(ValueLayout.JAVA_INT, 3, 4);
111 // dereference
112 int val00 = (int) abcx_multi.get(a, 0, 0); // a->b[0]->c[0] = 1
113 assertEquals(val00, 1);
114 int val10 = (int) abcx_multi.get(a, 1, 0); // a->b[1]->c[0] = 3
115 assertEquals(val10, 3);
116 int val01 = (int) abcx_multi.get(a, 0, 1); // a->b[0]->c[1] = 2
117 assertEquals(val01, 2);
118 int val11 = (int) abcx_multi.get(a, 1, 1); // a->b[1]->c[1] = 4
119 assertEquals(val11, 4);
120 }
121 }
122
123 @Test(expectedExceptions = IllegalArgumentException.class)
124 void testBadDerefInSelect() {
125 A.select(PathElement.groupElement("b"), PathElement.dereferenceElement());
126 }
127
128 @Test(expectedExceptions = IllegalArgumentException.class)
129 void testBadDerefInOffset() {
130 A.byteOffset(PathElement.groupElement("b"), PathElement.dereferenceElement());
131 }
132
133 @Test(expectedExceptions = IllegalArgumentException.class)
134 void testBadDerefInSlice() {
135 A.sliceHandle(PathElement.groupElement("b"), PathElement.dereferenceElement());
136 }
137
138 static final MemoryLayout A_MULTI_NO_TARGET = MemoryLayout.structLayout(
139 ValueLayout.ADDRESS.withName("bs")
140 );
141
142 @Test(expectedExceptions = IllegalArgumentException.class)
143 void badDerefAddressNoTarget() {
144 A_MULTI_NO_TARGET.varHandle(PathElement.groupElement("bs"), PathElement.dereferenceElement());
145 }
146
147 @Test(expectedExceptions = IllegalArgumentException.class)
148 void badDerefMisAligned() {
149 MemoryLayout struct = MemoryLayout.structLayout(
150 ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_INT).withName("x"));
151
152 try (Arena arena = Arena.ofConfined()) {
153 MemorySegment segment = arena.allocate(struct.byteSize() + 1).asSlice(1);
154 VarHandle vhX = struct.varHandle(PathElement.groupElement("x"), PathElement.dereferenceElement());
155 vhX.set(segment, 42); // should throw
156 }
157 }
158 }
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 /*
26 * @test
27 * @run testng TestDereferencePath
28 */
29
30 import java.lang.foreign.Arena;
31 import java.lang.foreign.MemoryLayout;
32 import java.lang.foreign.MemoryLayout.PathElement;
33 import java.lang.foreign.MemorySegment;
34
35 import java.lang.foreign.ValueLayout;
36
37 import org.testng.annotations.*;
38
39 import java.lang.invoke.VarHandle;
40 import static org.testng.Assert.*;
41
42 public class TestDereferencePath {
43
44 static final MemoryLayout C = MemoryLayout.structLayout(
45 ValueLayout.JAVA_INT.withName("x")
46 );
55 .withTargetLayout(B)
56 );
57
58 static final VarHandle abcx = A.varHandle(
59 PathElement.groupElement("b"), PathElement.dereferenceElement(),
60 PathElement.groupElement("c"), PathElement.dereferenceElement(),
61 PathElement.groupElement("x"));
62
63 @Test
64 public void testSingle() {
65 try (Arena arena = Arena.ofConfined()) {
66 // init structs
67 MemorySegment a = arena.allocate(A);
68 MemorySegment b = arena.allocate(B);
69 MemorySegment c = arena.allocate(C);
70 // init struct fields
71 a.set(ValueLayout.ADDRESS, 0, b);
72 b.set(ValueLayout.ADDRESS, 0, c);
73 c.set(ValueLayout.JAVA_INT, 0, 42);
74 // dereference
75 int val = (int) abcx.get(a, 0L);
76 assertEquals(val, 42);
77 }
78 }
79
80 static final MemoryLayout B_MULTI = MemoryLayout.structLayout(
81 ValueLayout.ADDRESS.withName("cs")
82 .withTargetLayout(MemoryLayout.sequenceLayout(2, C))
83 );
84
85 static final MemoryLayout A_MULTI = MemoryLayout.structLayout(
86 ValueLayout.ADDRESS.withName("bs")
87 .withTargetLayout(MemoryLayout.sequenceLayout(2, B_MULTI))
88 );
89
90 static final VarHandle abcx_multi = A_MULTI.varHandle(
91 PathElement.groupElement("bs"), PathElement.dereferenceElement(), PathElement.sequenceElement(),
92 PathElement.groupElement("cs"), PathElement.dereferenceElement(), PathElement.sequenceElement(),
93 PathElement.groupElement("x"));
94
95 @Test
96 public void testMulti() {
97 try (Arena arena = Arena.ofConfined()) {
98 // init structs
99 MemorySegment a = arena.allocate(A);
100 MemorySegment b = arena.allocate(B, 2);
101 MemorySegment c = arena.allocate(C, 4);
102 // init struct fields
103 a.set(ValueLayout.ADDRESS, 0, b);
104 b.set(ValueLayout.ADDRESS, 0, c);
105 b.setAtIndex(ValueLayout.ADDRESS, 1, c.asSlice(C.byteSize() * 2));
106 c.setAtIndex(ValueLayout.JAVA_INT, 0, 1);
107 c.setAtIndex(ValueLayout.JAVA_INT, 1, 2);
108 c.setAtIndex(ValueLayout.JAVA_INT, 2, 3);
109 c.setAtIndex(ValueLayout.JAVA_INT, 3, 4);
110 // dereference
111 int val00 = (int) abcx_multi.get(a, 0L, 0, 0); // a->b[0]->c[0] = 1
112 assertEquals(val00, 1);
113 int val10 = (int) abcx_multi.get(a, 0L, 1, 0); // a->b[1]->c[0] = 3
114 assertEquals(val10, 3);
115 int val01 = (int) abcx_multi.get(a, 0L, 0, 1); // a->b[0]->c[1] = 2
116 assertEquals(val01, 2);
117 int val11 = (int) abcx_multi.get(a, 0L, 1, 1); // a->b[1]->c[1] = 4
118 assertEquals(val11, 4);
119 }
120 }
121
122 @Test(expectedExceptions = IllegalArgumentException.class)
123 void testBadDerefInSelect() {
124 A.select(PathElement.groupElement("b"), PathElement.dereferenceElement());
125 }
126
127 @Test(expectedExceptions = IllegalArgumentException.class)
128 void testBadDerefInOffset() {
129 A.byteOffset(PathElement.groupElement("b"), PathElement.dereferenceElement());
130 }
131
132 @Test(expectedExceptions = IllegalArgumentException.class)
133 void testBadDerefInSlice() {
134 A.sliceHandle(PathElement.groupElement("b"), PathElement.dereferenceElement());
135 }
136
137 static final MemoryLayout A_MULTI_NO_TARGET = MemoryLayout.structLayout(
138 ValueLayout.ADDRESS.withName("bs")
139 );
140
141 @Test(expectedExceptions = IllegalArgumentException.class)
142 void badDerefAddressNoTarget() {
143 A_MULTI_NO_TARGET.varHandle(PathElement.groupElement("bs"), PathElement.dereferenceElement());
144 }
145
146 @Test(expectedExceptions = IllegalArgumentException.class)
147 void badDerefMisAligned() {
148 MemoryLayout struct = MemoryLayout.structLayout(
149 ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_INT).withName("x"));
150
151 try (Arena arena = Arena.ofConfined()) {
152 MemorySegment segment = arena.allocate(struct.byteSize() + 1).asSlice(1);
153 VarHandle vhX = struct.varHandle(PathElement.groupElement("x"), PathElement.dereferenceElement());
154 vhX.set(segment, 0L, 42); // should throw
155 }
156 }
157 }
|