1 /* 2 * Copyright (c) 2019, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.lang.foreign; 27 28 import java.lang.invoke.MethodHandles; 29 import java.lang.invoke.VarHandle; 30 import java.nio.ByteOrder; 31 32 import jdk.internal.foreign.layout.ValueLayouts; 33 import jdk.internal.javac.PreviewFeature; 34 35 /** 36 * A layout that models values of basic data types. Examples of values modelled by a value layout are 37 * <em>integral</em> values (either signed or unsigned), <em>floating-point</em> values and 38 * <em>address</em> values. 39 * <p> 40 * Each value layout has a size, an alignment (both expressed in bytes), 41 * a {@linkplain ByteOrder byte order}, and a <em>carrier</em>, that is, the Java type that should be used when 42 * {@linkplain MemorySegment#get(OfInt, long) accessing} a region of memory using the value layout. 43 * <p> 44 * This class defines useful value layout constants for Java primitive types and addresses. 45 * @apiNote Some characteristics of the Java layout constants are platform-dependent. For instance, the byte order of 46 * these constants is set to the {@linkplain ByteOrder#nativeOrder() native byte order}, thus making it easy to work 47 * with other APIs, such as arrays and {@link java.nio.ByteBuffer}. Moreover, the alignment constraint of 48 * {@link ValueLayout#JAVA_LONG} and {@link ValueLayout#JAVA_DOUBLE} is set to 8 bytes on 64-bit platforms, but only to 49 * 4 bytes on 32-bit platforms. 50 * 51 * @implSpec implementing classes and subclasses are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>. 52 * 53 * @sealedGraph 54 * @since 19 55 */ 56 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) 57 public sealed interface ValueLayout extends MemoryLayout permits 58 ValueLayout.OfBoolean, ValueLayout.OfByte, ValueLayout.OfChar, ValueLayout.OfShort, ValueLayout.OfInt, 59 ValueLayout.OfFloat, ValueLayout.OfLong, ValueLayout.OfDouble, AddressLayout { 60 61 /** 62 * {@return the value's byte order} 63 */ 64 ByteOrder order(); 65 66 /** 67 * {@return a value layout with the same characteristics as this layout, but with the given byte order} 68 * 69 * @param order the desired byte order. 70 */ 71 ValueLayout withOrder(ByteOrder order); 72 73 /** 74 * {@inheritDoc} 75 */ 76 @Override 77 ValueLayout withoutName(); 78 79 /** 80 * Creates a <em>strided</em> var handle that can be used to access a memory segment as multi-dimensional 81 * array. This array has a notional sequence layout featuring {@code shape.length} nested sequence layouts. The element 82 * layout of the innermost sequence layout in the notional sequence layout is this value layout. The resulting var handle 83 * is obtained as if calling the {@link #varHandle(PathElement...)} method on the notional layout, with a layout 84 * path containing exactly {@code shape.length + 1} {@linkplain PathElement#sequenceElement() open sequence layout path elements}. 85 * <p> 86 * For instance, the following method call: 87 * 88 * {@snippet lang=java : 89 * VarHandle arrayHandle = ValueLayout.JAVA_INT.arrayElementVarHandle(10, 20); 90 * } 91 * 92 * Is equivalent to the following code: 93 * 94 * {@snippet lang = java: 95 * SequenceLayout notionalLayout = MemoryLayout.sequenceLayout( 96 * MemoryLayout.sequenceLayout(10, MemoryLayout.sequenceLayout(20, ValueLayout.JAVA_INT))); 97 * VarHandle arrayHandle = notionalLayout.varHandle(PathElement.sequenceElement(), 98 * PathElement.sequenceElement(), 99 * PathElement.sequenceElement()); 100 *} 101 * 102 * The resulting var handle {@code arrayHandle} will feature 3 coordinates of type {@code long}; each coordinate 103 * is interpreted as an index into the corresponding sequence layout. If we refer to the var handle coordinates, from left 104 * to right, as {@code x}, {@code y} and {@code z} respectively, the final offset accessed by the var handle can be 105 * computed with the following formula: 106 * 107 * <blockquote><pre>{@code 108 * offset = (10 * 20 * 4 * x) + (20 * 4 * y) + (4 * z) 109 * }</pre></blockquote> 110 * 111 * Additionally, the values of {@code x}, {@code y} and {@code z} are constrained as follows: 112 * <ul> 113 * <li>{@code 0 <= x < notionalLayout.elementCount() }</li> 114 * <li>{@code 0 <= y < 10 }</li> 115 * <li>{@code 0 <= z < 20 }</li> 116 * </ul> 117 * <p> 118 * Consider the following access expressions: 119 * {@snippet lang=java : 120 * int value1 = (int) arrayHandle.get(10, 2, 4); // ok, accessed offset = 8176 121 * int value2 = (int) arrayHandle.get(0, 0, 30); // out of bounds value for z 122 * } 123 * In the first case, access is well-formed, as the values for {@code x}, {@code y} and {@code z} conform to 124 * the bounds specified above. In the second case, access fails with {@link IndexOutOfBoundsException}, 125 * as the value for {@code z} is outside its specified bounds. 126 * 127 * @param shape the size of each nested array dimension. 128 * @return a var handle which can be used to access a memory segment as a multi-dimensional array, 129 * featuring {@code shape.length + 1} 130 * {@code long} coordinates. 131 * @throws IllegalArgumentException if {@code shape[i] < 0}, for at least one index {@code i}. 132 * @throws UnsupportedOperationException if {@code byteAlignment() > byteSize()}. 133 * @see MethodHandles#memorySegmentViewVarHandle 134 * @see MemoryLayout#varHandle(PathElement...) 135 * @see SequenceLayout 136 */ 137 VarHandle arrayElementVarHandle(int... shape); 138 139 /** 140 * {@return the carrier associated with this value layout} 141 */ 142 Class<?> carrier(); 143 144 /** 145 * {@inheritDoc} 146 */ 147 @Override 148 ValueLayout withName(String name); 149 150 /** 151 * {@inheritDoc} 152 * @throws IllegalArgumentException {@inheritDoc} 153 */ 154 @Override 155 ValueLayout withByteAlignment(long byteAlignment); 156 157 /** 158 * A value layout whose carrier is {@code boolean.class}. 159 * 160 * @see #JAVA_BOOLEAN 161 * @since 19 162 */ 163 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 164 sealed interface OfBoolean extends ValueLayout permits ValueLayouts.OfBooleanImpl { 165 166 /** 167 * {@inheritDoc} 168 */ 169 @Override 170 OfBoolean withName(String name); 171 172 /** 173 * {@inheritDoc} 174 */ 175 @Override 176 OfBoolean withoutName(); 177 178 /** 179 * {@inheritDoc} 180 * @throws IllegalArgumentException {@inheritDoc} 181 */ 182 @Override 183 OfBoolean withByteAlignment(long byteAlignment); 184 185 /** 186 * {@inheritDoc} 187 */ 188 @Override 189 OfBoolean withOrder(ByteOrder order); 190 191 } 192 193 /** 194 * A value layout whose carrier is {@code byte.class}. 195 * 196 * @see #JAVA_BYTE 197 * @since 19 198 */ 199 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 200 sealed interface OfByte extends ValueLayout permits ValueLayouts.OfByteImpl { 201 202 /** 203 * {@inheritDoc} 204 */ 205 @Override 206 OfByte withName(String name); 207 208 /** 209 * {@inheritDoc} 210 */ 211 @Override 212 OfByte withoutName(); 213 214 /** 215 * {@inheritDoc} 216 * @throws IllegalArgumentException {@inheritDoc} 217 */ 218 @Override 219 OfByte withByteAlignment(long byteAlignment); 220 221 /** 222 * {@inheritDoc} 223 */ 224 @Override 225 OfByte withOrder(ByteOrder order); 226 227 } 228 229 /** 230 * A value layout whose carrier is {@code char.class}. 231 * 232 * @see #JAVA_CHAR 233 * @see #JAVA_CHAR_UNALIGNED 234 * @since 19 235 */ 236 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 237 sealed interface OfChar extends ValueLayout permits ValueLayouts.OfCharImpl { 238 239 /** 240 * {@inheritDoc} 241 */ 242 @Override 243 OfChar withName(String name); 244 245 /** 246 * {@inheritDoc} 247 */ 248 @Override 249 OfChar withoutName(); 250 251 /** 252 * {@inheritDoc} 253 * @throws IllegalArgumentException {@inheritDoc} 254 */ 255 @Override 256 OfChar withByteAlignment(long byteAlignment); 257 258 /** 259 * {@inheritDoc} 260 */ 261 @Override 262 OfChar withOrder(ByteOrder order); 263 264 } 265 266 /** 267 * A value layout whose carrier is {@code short.class}. 268 * 269 * @see #JAVA_SHORT 270 * @see #JAVA_SHORT_UNALIGNED 271 * @since 19 272 */ 273 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 274 sealed interface OfShort extends ValueLayout permits ValueLayouts.OfShortImpl { 275 276 /** 277 * {@inheritDoc} 278 */ 279 @Override 280 OfShort withName(String name); 281 282 /** 283 * {@inheritDoc} 284 */ 285 @Override 286 OfShort withoutName(); 287 288 /** 289 * {@inheritDoc} 290 * @throws IllegalArgumentException {@inheritDoc} 291 */ 292 @Override 293 OfShort withByteAlignment(long byteAlignment); 294 295 /** 296 * {@inheritDoc} 297 */ 298 @Override 299 OfShort withOrder(ByteOrder order); 300 301 } 302 303 /** 304 * A value layout whose carrier is {@code int.class}. 305 * 306 * @see #JAVA_INT 307 * @see #JAVA_INT_UNALIGNED 308 * @since 19 309 */ 310 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 311 sealed interface OfInt extends ValueLayout permits ValueLayouts.OfIntImpl { 312 313 /** 314 * {@inheritDoc} 315 */ 316 @Override 317 OfInt withName(String name); 318 319 /** 320 * {@inheritDoc} 321 */ 322 @Override 323 OfInt withoutName(); 324 325 /** 326 * {@inheritDoc} 327 * @throws IllegalArgumentException {@inheritDoc} 328 */ 329 @Override 330 OfInt withByteAlignment(long byteAlignment); 331 332 /** 333 * {@inheritDoc} 334 */ 335 @Override 336 OfInt withOrder(ByteOrder order); 337 338 } 339 340 /** 341 * A value layout whose carrier is {@code float.class}. 342 * 343 * @see #JAVA_FLOAT 344 * @see #JAVA_FLOAT_UNALIGNED 345 * @since 19 346 */ 347 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 348 sealed interface OfFloat extends ValueLayout permits ValueLayouts.OfFloatImpl { 349 350 /** 351 * {@inheritDoc} 352 */ 353 @Override 354 OfFloat withName(String name); 355 356 /** 357 * {@inheritDoc} 358 */ 359 @Override 360 OfFloat withoutName(); 361 362 /** 363 * {@inheritDoc} 364 */ 365 @Override 366 OfFloat withByteAlignment(long byteAlignment); 367 368 /** 369 * {@inheritDoc} 370 */ 371 @Override 372 OfFloat withOrder(ByteOrder order); 373 374 } 375 376 /** 377 * A value layout whose carrier is {@code long.class}. 378 * 379 * @see #JAVA_LONG 380 * @see #JAVA_LONG_UNALIGNED 381 * @since 19 382 */ 383 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 384 sealed interface OfLong extends ValueLayout permits ValueLayouts.OfLongImpl { 385 386 /** 387 * {@inheritDoc} 388 */ 389 @Override 390 OfLong withName(String name); 391 392 /** 393 * {@inheritDoc} 394 */ 395 @Override 396 OfLong withoutName(); 397 398 /** 399 * {@inheritDoc} 400 * @throws IllegalArgumentException {@inheritDoc} 401 */ 402 @Override 403 OfLong withByteAlignment(long byteAlignment); 404 405 /** 406 * {@inheritDoc} 407 */ 408 @Override 409 OfLong withOrder(ByteOrder order); 410 411 } 412 413 /** 414 * A value layout whose carrier is {@code double.class}. 415 * 416 * @see #JAVA_DOUBLE 417 * @see #JAVA_DOUBLE_UNALIGNED 418 * @since 19 419 */ 420 @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN) 421 sealed interface OfDouble extends ValueLayout permits ValueLayouts.OfDoubleImpl { 422 423 /** 424 * {@inheritDoc} 425 */ 426 @Override 427 OfDouble withName(String name); 428 429 /** 430 * {@inheritDoc} 431 */ 432 @Override 433 OfDouble withoutName(); 434 435 /** 436 * {@inheritDoc} 437 * @throws IllegalArgumentException {@inheritDoc} 438 */ 439 @Override 440 OfDouble withByteAlignment(long byteAlignment); 441 442 /** 443 * {@inheritDoc} 444 */ 445 @Override 446 OfDouble withOrder(ByteOrder order); 447 448 } 449 450 /** 451 * An address layout constant whose size is the same as that of a machine address ({@code size_t}), 452 * byte alignment set to {@code sizeof(size_t)}, byte order set to {@link ByteOrder#nativeOrder()}. 453 */ 454 AddressLayout ADDRESS = ValueLayouts.OfAddressImpl.of(ByteOrder.nativeOrder()); 455 456 /** 457 * A value layout constant whose size is the same as that of a Java {@code byte}, 458 * byte alignment set to 1, and byte order set to {@link ByteOrder#nativeOrder()}. 459 */ 460 OfByte JAVA_BYTE = ValueLayouts.OfByteImpl.of(ByteOrder.nativeOrder()); 461 462 /** 463 * A value layout constant whose size is the same as that of a Java {@code boolean}, 464 * byte alignment set to 1, and byte order set to {@link ByteOrder#nativeOrder()}. 465 */ 466 OfBoolean JAVA_BOOLEAN = ValueLayouts.OfBooleanImpl.of(ByteOrder.nativeOrder()); 467 468 /** 469 * A value layout constant whose size is the same as that of a Java {@code char}, 470 * byte alignment set to 2, and byte order set to {@link ByteOrder#nativeOrder()}. 471 */ 472 OfChar JAVA_CHAR = ValueLayouts.OfCharImpl.of(ByteOrder.nativeOrder()); 473 474 /** 475 * A value layout constant whose size is the same as that of a Java {@code short}, 476 * byte alignment set to 2, and byte order set to {@link ByteOrder#nativeOrder()}. 477 */ 478 OfShort JAVA_SHORT = ValueLayouts.OfShortImpl.of(ByteOrder.nativeOrder()); 479 480 /** 481 * A value layout constant whose size is the same as that of a Java {@code int}, 482 * byte alignment set to 4, and byte order set to {@link ByteOrder#nativeOrder()}. 483 */ 484 OfInt JAVA_INT = ValueLayouts.OfIntImpl.of(ByteOrder.nativeOrder()); 485 486 /** 487 * A value layout constant whose size is the same as that of a Java {@code long}, 488 * (platform-dependent) byte alignment set to {@code ADDRESS.byteSize()}, 489 * and byte order set to {@link ByteOrder#nativeOrder()}. 490 */ 491 OfLong JAVA_LONG = ValueLayouts.OfLongImpl.of(ByteOrder.nativeOrder()); 492 493 /** 494 * A value layout constant whose size is the same as that of a Java {@code float}, 495 * byte alignment set to 4, and byte order set to {@link ByteOrder#nativeOrder()}. 496 */ 497 OfFloat JAVA_FLOAT = ValueLayouts.OfFloatImpl.of(ByteOrder.nativeOrder()); 498 499 /** 500 * A value layout constant whose size is the same as that of a Java {@code double}, 501 * (platform-dependent) byte alignment set to {@code ADDRESS.byteSize()}, 502 * and byte order set to {@link ByteOrder#nativeOrder()}. 503 */ 504 OfDouble JAVA_DOUBLE = ValueLayouts.OfDoubleImpl.of(ByteOrder.nativeOrder()); 505 506 /** 507 * An unaligned address layout constant whose size is the same as that of a machine address ({@code size_t}), 508 * and byte order set to {@link ByteOrder#nativeOrder()}. 509 * Equivalent to the following code: 510 * {@snippet lang=java : 511 * ADDRESS.withByteAlignment(1); 512 * } 513 * @apiNote Care should be taken when using unaligned value layouts as they may induce 514 * performance and portability issues. 515 */ 516 AddressLayout ADDRESS_UNALIGNED = ADDRESS.withByteAlignment(1); 517 518 /** 519 * An unaligned value layout constant whose size is the same as that of a Java {@code char} 520 * and byte order set to {@link ByteOrder#nativeOrder()}. 521 * Equivalent to the following code: 522 * {@snippet lang=java : 523 * JAVA_CHAR.withByteAlignment(1); 524 * } 525 * @apiNote Care should be taken when using unaligned value layouts as they may induce 526 * performance and portability issues. 527 */ 528 OfChar JAVA_CHAR_UNALIGNED = JAVA_CHAR.withByteAlignment(1); 529 530 /** 531 * An unaligned value layout constant whose size is the same as that of a Java {@code short} 532 * and byte order set to {@link ByteOrder#nativeOrder()}. 533 * Equivalent to the following code: 534 * {@snippet lang=java : 535 * JAVA_SHORT.withByteAlignment(1); 536 * } 537 * @apiNote Care should be taken when using unaligned value layouts as they may induce 538 * performance and portability issues. 539 */ 540 OfShort JAVA_SHORT_UNALIGNED = JAVA_SHORT.withByteAlignment(1); 541 542 /** 543 * An unaligned value layout constant whose size is the same as that of a Java {@code int} 544 * and byte order set to {@link ByteOrder#nativeOrder()}. 545 * Equivalent to the following code: 546 * {@snippet lang=java : 547 * JAVA_INT.withByteAlignment(1); 548 * } 549 * @apiNote Care should be taken when using unaligned value layouts as they may induce 550 * performance and portability issues. 551 */ 552 OfInt JAVA_INT_UNALIGNED = JAVA_INT.withByteAlignment(1); 553 554 /** 555 * An unaligned value layout constant whose size is the same as that of a Java {@code long} 556 * and byte order set to {@link ByteOrder#nativeOrder()}. 557 * Equivalent to the following code: 558 * {@snippet lang=java : 559 * JAVA_LONG.withByteAlignment(1); 560 * } 561 * @apiNote Care should be taken when using unaligned value layouts as they may induce 562 * performance and portability issues. 563 */ 564 OfLong JAVA_LONG_UNALIGNED = JAVA_LONG.withByteAlignment(1); 565 566 /** 567 * An unaligned value layout constant whose size is the same as that of a Java {@code float} 568 * and byte order set to {@link ByteOrder#nativeOrder()}. 569 * Equivalent to the following code: 570 * {@snippet lang=java : 571 * JAVA_FLOAT.withByteAlignment(1); 572 * } 573 * @apiNote Care should be taken when using unaligned value layouts as they may induce 574 * performance and portability issues. 575 */ 576 OfFloat JAVA_FLOAT_UNALIGNED = JAVA_FLOAT.withByteAlignment(1); 577 578 /** 579 * An unaligned value layout constant whose size is the same as that of a Java {@code double} 580 * and byte order set to {@link ByteOrder#nativeOrder()}. 581 * Equivalent to the following code: 582 * {@snippet lang=java : 583 * JAVA_DOUBLE.withByteAlignment(1); 584 * } 585 * @apiNote Care should be taken when using unaligned value layouts as they may induce 586 * performance and portability issues. 587 */ 588 OfDouble JAVA_DOUBLE_UNALIGNED = JAVA_DOUBLE.withByteAlignment(1); 589 590 }