1 /*
  2  * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  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  * @test
 26  * @enablePreview
 27  * @run testng/othervm MemoryLayoutTypeRetentionTest
 28  */
 29 
 30 import org.testng.annotations.*;
 31 
 32 import java.lang.foreign.*;
 33 import java.nio.ByteOrder;
 34 
 35 import static java.lang.foreign.ValueLayout.*;
 36 import static org.testng.Assert.*;
 37 
 38 public class MemoryLayoutTypeRetentionTest {
 39 
 40     // These tests check both compile-time and runtime properties.
 41     // withName() et al. should return the same type as the original object.
 42 
 43     private static final String NAME = "a";
 44     private static final long BYTE_ALIGNMENT = Byte.BYTES;
 45     private static final ByteOrder BYTE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN
 46             ? ByteOrder.LITTLE_ENDIAN
 47             : ByteOrder.BIG_ENDIAN;
 48 
 49     @Test
 50     public void testOfBoolean() {
 51         OfBoolean v = JAVA_BOOLEAN
 52                 .withByteAlignment(BYTE_ALIGNMENT)
 53                 .withoutName()
 54                 .withName(NAME)
 55                 .withOrder(BYTE_ORDER);
 56         check(v);
 57     }
 58 
 59     @Test
 60     public void testOfByte() {
 61         OfByte v = JAVA_BYTE
 62                 .withByteAlignment(BYTE_ALIGNMENT)
 63                 .withoutName()
 64                 .withName(NAME)
 65                 .withOrder(BYTE_ORDER);
 66         check(v);
 67     }
 68 
 69     @Test
 70     public void testOfShort() {
 71         OfShort v = JAVA_SHORT
 72                 .withByteAlignment(BYTE_ALIGNMENT)
 73                 .withoutName()
 74                 .withName(NAME)
 75                 .withOrder(BYTE_ORDER);
 76         check(v);
 77     }
 78 
 79     @Test
 80     public void testOfInt() {
 81         OfInt v = JAVA_INT
 82                 .withByteAlignment(BYTE_ALIGNMENT)
 83                 .withoutName()
 84                 .withName(NAME)
 85                 .withOrder(BYTE_ORDER);
 86         check(v);
 87     }
 88 
 89     @Test
 90     public void testOfChar() {
 91         OfChar v = JAVA_CHAR
 92                 .withByteAlignment(BYTE_ALIGNMENT)
 93                 .withoutName()
 94                 .withName(NAME)
 95                 .withOrder(BYTE_ORDER);
 96         check(v);
 97     }
 98 
 99     @Test
100     public void testOfLong() {
101         OfLong v = JAVA_LONG
102                 .withByteAlignment(BYTE_ALIGNMENT)
103                 .withoutName()
104                 .withName(NAME)
105                 .withOrder(BYTE_ORDER);
106         check(v);
107     }
108 
109     @Test
110     public void testOfFloat() {
111         OfFloat v = JAVA_FLOAT
112                 .withByteAlignment(BYTE_ALIGNMENT)
113                 .withoutName()
114                 .withName(NAME)
115                 .withOrder(BYTE_ORDER);
116         check(v);
117     }
118 
119     @Test
120     public void testOfDouble() {
121         OfDouble v = JAVA_DOUBLE
122                 .withByteAlignment(BYTE_ALIGNMENT)
123                 .withoutName()
124                 .withName(NAME)
125                 .withOrder(BYTE_ORDER);
126         check(v);
127     }
128 
129     @Test
130     public void testValueLayout() {
131         ValueLayout v = ((ValueLayout) JAVA_INT)
132                 .withByteAlignment(BYTE_ALIGNMENT)
133                 .withoutName()
134                 .withName(NAME)
135                 .withOrder(BYTE_ORDER);
136         check(v);
137     }
138 
139     @Test
140     public void testAddressLayout() {
141         AddressLayout v = ADDRESS
142                 .withByteAlignment(BYTE_ALIGNMENT)
143                 .withoutName()
144                 .withName(NAME)
145                 .withoutTargetLayout()
146                 .withOrder(BYTE_ORDER);
147         check(v);
148         assertEquals(v.order(), BYTE_ORDER);
149 
150         assertFalse(v.targetLayout().isPresent());
151         AddressLayout v2 = v.withTargetLayout(JAVA_INT);
152         assertTrue(v2.targetLayout().isPresent());
153         assertEquals(v2.targetLayout().get(), JAVA_INT);
154         assertTrue(v2.withoutTargetLayout().targetLayout().isEmpty());
155     }
156 
157     @Test
158     public void testPaddingLayout() {
159         PaddingLayout v = MemoryLayout.paddingLayout(1)
160                 .withByteAlignment(BYTE_ALIGNMENT)
161                 .withoutName()
162                 .withName(NAME);
163         check(v);
164     }
165 
166     @Test
167     public void testGroupLayout() {
168         GroupLayout v = MemoryLayout.structLayout(
169                         JAVA_INT.withByteAlignment(BYTE_ALIGNMENT),
170                         JAVA_LONG.withByteAlignment(BYTE_ALIGNMENT))
171                 .withByteAlignment(BYTE_ALIGNMENT)
172                 .withoutName()
173                 .withName(NAME);
174         check(v);
175     }
176 
177     @Test
178     public void testStructLayout() {
179         StructLayout v = MemoryLayout.structLayout(
180                         JAVA_INT.withByteAlignment(BYTE_ALIGNMENT),
181                         JAVA_LONG.withByteAlignment(BYTE_ALIGNMENT))
182                 .withByteAlignment(BYTE_ALIGNMENT)
183                 .withoutName()
184                 .withName(NAME);
185         check(v);
186     }
187 
188     @Test
189     public void testUnionLayout() {
190         UnionLayout v = MemoryLayout.unionLayout(
191                     JAVA_INT.withByteAlignment(BYTE_ALIGNMENT),
192                     JAVA_LONG.withByteAlignment(BYTE_ALIGNMENT))
193                 .withByteAlignment(BYTE_ALIGNMENT)
194                 .withoutName()
195                 .withName(NAME);
196         check(v);
197     }
198 
199     public void check(ValueLayout v) {
200         check((MemoryLayout) v);
201         assertEquals(v.order(), BYTE_ORDER);
202     }
203 
204     public void check(MemoryLayout v) {
205         // Check name properties
206         assertEquals(v.name().orElseThrow(), NAME);
207         assertTrue(v.withoutName().name().isEmpty());
208 
209         assertEquals(v.byteAlignment(), BYTE_ALIGNMENT);
210     }
211 
212 }