1 /* 2 * Copyright (c) 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.snippets; 27 28 import java.lang.foreign.AddressLayout; 29 import java.lang.foreign.Arena; 30 import java.lang.foreign.FunctionDescriptor; 31 import java.lang.foreign.Linker; 32 import java.lang.foreign.MemoryLayout; 33 import java.lang.foreign.MemorySegment; 34 import java.lang.foreign.SegmentAllocator; 35 import java.lang.foreign.SequenceLayout; 36 import java.lang.foreign.StructLayout; 37 import java.lang.foreign.SymbolLookup; 38 import java.lang.foreign.ValueLayout; 39 import java.lang.invoke.MethodHandle; 40 import java.lang.invoke.MethodHandles; 41 import java.lang.invoke.MethodType; 42 import java.lang.invoke.VarHandle; 43 import java.nio.ByteOrder; 44 import java.util.Objects; 45 import java.util.Optional; 46 import java.util.stream.Collectors; 47 import java.util.stream.StreamSupport; 48 49 import static java.lang.foreign.MemoryLayout.sequenceLayout; 50 import static java.lang.foreign.MemoryLayout.structLayout; 51 import static java.lang.foreign.SymbolLookup.libraryLookup; 52 import static java.lang.foreign.SymbolLookup.loaderLookup; 53 import static java.lang.foreign.ValueLayout.*; 54 import static java.nio.ByteOrder.BIG_ENDIAN; 55 56 /** 57 * Snippets for the java.lang.foreign documentation. 58 */ 59 class Snippets { 60 61 /** 62 * Creates a new snippet. 63 */ 64 public Snippets() { 65 } 66 67 static class ArenaSnippets { 68 69 void globalArena() { 70 // @start region="global-allocation": 71 MemorySegment segment = Arena.global().allocate(100, 1); // @highlight regex='global()' 72 // ... 73 // segment is never deallocated! 74 // @end 75 } 76 77 void autoArena() { 78 // @start region="auto-allocation": 79 MemorySegment segment = Arena.ofAuto().allocate(100, 1); // @highlight regex='ofAuto()' 80 // ... 81 segment = null; // the segment region becomes available for deallocation after this point 82 // @end 83 } 84 85 void confinedArena() { 86 // @start region="confined-allocation": 87 MemorySegment segment = null; 88 try (Arena arena = Arena.ofConfined()) { // @highlight regex='ofConfined()' 89 segment = arena.allocate(100); 90 // ... 91 } // segment region deallocated here 92 segment.get(ValueLayout.JAVA_BYTE, 0); // throws IllegalStateException 93 // @end 94 } 95 96 static 97 // @start region="slicing-arena": 98 class SlicingArena implements Arena { 99 final Arena arena = Arena.ofConfined(); 100 final SegmentAllocator slicingAllocator; 101 102 SlicingArena(long size) { 103 slicingAllocator = SegmentAllocator.slicingAllocator(arena.allocate(size)); 104 } 105 106 public MemorySegment allocate(long byteSize, long byteAlignment) { 107 return slicingAllocator.allocate(byteSize, byteAlignment); 108 } 109 110 public MemorySegment.Scope scope() { 111 return arena.scope(); 112 } 113 114 public void close() { 115 arena.close(); 116 } 117 118 } 119 // @end 120 121 public static void main(String[] args) { 122 // @start region="slicing-arena-main": 123 try (Arena slicingArena = new SlicingArena(1000)) { 124 for (int i = 0; i < 10; i++) { 125 MemorySegment s = slicingArena.allocateArray(JAVA_INT, 1, 2, 3, 4, 5); 126 // ... 127 } 128 } // all memory allocated is released here 129 // @end 130 } 131 132 void arenaOverlap() { 133 try (var arena = Arena.ofConfined()) { 134 var S1 = arena.allocate(16L); 135 var S2 = arena.allocate(16L); 136 137 if ( 138 // @start region="arena-overlap": 139 S1.asOverlappingSlice(S2).isEmpty() == true 140 // @end 141 ) {} 142 143 } 144 } 145 } 146 147 static class AddressLayoutSnippets { 148 void withTargetLayout() { 149 AddressLayout addressLayout = ADDRESS; 150 AddressLayout unboundedLayout = addressLayout.withTargetLayout( 151 sequenceLayout(ValueLayout.JAVA_BYTE)); 152 } 153 } 154 155 static class FunctionDescriptionSnippets { 156 } 157 158 static class GroupLayoutSnippets { 159 } 160 161 static class LinkerSnippets { 162 163 void downcall() throws Throwable { 164 Linker linker = Linker.nativeLinker(); 165 MethodHandle strlen = linker.downcallHandle( 166 linker.defaultLookup().find("strlen").orElseThrow(), 167 FunctionDescriptor.of(JAVA_LONG, ADDRESS) 168 ); 169 170 try (Arena arena = Arena.ofConfined()) { 171 MemorySegment str = arena.allocateUtf8String("Hello"); 172 long len = (long) strlen.invokeExact(str); // 5 173 } 174 175 } 176 177 void qsort() throws Throwable { 178 Linker linker = Linker.nativeLinker(); 179 MethodHandle qsort = linker.downcallHandle( 180 linker.defaultLookup().find("qsort").orElseThrow(), 181 FunctionDescriptor.ofVoid(ADDRESS, JAVA_LONG, JAVA_LONG, ADDRESS) 182 ); 183 184 class Qsort { 185 static int qsortCompare(MemorySegment elem1, MemorySegment elem2) { 186 return Integer.compare(elem1.get(JAVA_INT, 0), elem2.get(JAVA_INT, 0)); 187 } 188 } 189 190 FunctionDescriptor comparDesc = FunctionDescriptor.of(JAVA_INT, 191 ADDRESS.withTargetLayout(JAVA_INT), 192 ADDRESS.withTargetLayout(JAVA_INT)); 193 MethodHandle comparHandle = MethodHandles.lookup() 194 .findStatic(Qsort.class, "qsortCompare", 195 comparDesc.toMethodType()); 196 197 198 try (Arena arena = Arena.ofConfined()) { 199 MemorySegment compareFunc = linker.upcallStub(comparHandle, comparDesc, arena); 200 MemorySegment array = arena.allocateArray(JAVA_INT, 0, 9, 3, 4, 6, 5, 1, 8, 2, 7); 201 qsort.invokeExact(array, 10L, 4L, compareFunc); 202 int[] sorted = array.toArray(JAVA_INT); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] 203 204 } 205 } 206 207 void returnPointer() throws Throwable { 208 Linker linker = Linker.nativeLinker(); 209 210 MethodHandle malloc = linker.downcallHandle( 211 linker.defaultLookup().find("malloc").orElseThrow(), 212 FunctionDescriptor.of(ADDRESS, JAVA_LONG) 213 ); 214 215 MethodHandle free = linker.downcallHandle( 216 linker.defaultLookup().find("free").orElseThrow(), 217 FunctionDescriptor.ofVoid(ADDRESS) 218 ); 219 220 MemorySegment segment = (MemorySegment) malloc.invokeExact(100); 221 222 class AllocateMemory { 223 224 MemorySegment allocateMemory(long byteSize, Arena arena) throws Throwable { 225 MemorySegment segment = (MemorySegment) malloc.invokeExact(byteSize); // size = 0, scope = always alive 226 return segment.reinterpret(byteSize, arena, s -> { 227 try { 228 free.invokeExact(s); 229 } catch (Throwable e) { 230 throw new RuntimeException(e); 231 } 232 }); // size = byteSize, scope = arena.scope() 233 } 234 235 } 236 237 238 class AllocateMemory2 { 239 240 MemorySegment allocateMemory(long byteSize, Arena arena) { 241 MemorySegment segment = trySupplier(() -> (MemorySegment) malloc.invokeExact(byteSize)); // size = 0, scope = always alive 242 return segment.reinterpret(byteSize, arena, s -> trySupplier(() -> free.invokeExact(s))); // size = byteSize, scope = arena.scope() 243 } 244 245 @FunctionalInterface 246 interface ThrowingSupplier<T> { 247 T get() throws Throwable; 248 249 } 250 251 <T> T trySupplier(ThrowingSupplier<? extends T> supplier) { 252 try { 253 return supplier.get(); 254 } catch (Throwable t) { 255 throw new RuntimeException(t); 256 } 257 } 258 259 260 } 261 262 263 class AllocateMemory3 { 264 265 MemorySegment allocateMemory(long byteSize, Arena arena) throws Throwable { 266 MemorySegment segment = (MemorySegment) malloc.invokeExact(byteSize); // size = 0, scope = always alive 267 return segment.reinterpret(byteSize, arena, this::freeMemory); // size = byteSize, scope = arena.scope() 268 } 269 270 void freeMemory(MemorySegment segment) { 271 try { 272 free.invokeExact(segment); 273 } catch (Throwable e) { 274 throw new RuntimeException(e); 275 } 276 } 277 } 278 279 } 280 281 void variadicFunc() throws Throwable { 282 283 Linker linker = Linker.nativeLinker(); 284 MethodHandle printf = linker.downcallHandle( 285 linker.defaultLookup().find("printf").orElseThrow(), 286 FunctionDescriptor.of(JAVA_INT, ADDRESS, JAVA_INT, JAVA_INT, JAVA_INT), 287 Linker.Option.firstVariadicArg(1) // first int is variadic 288 ); 289 290 try (Arena arena = Arena.ofConfined()) { 291 int res = (int) printf.invokeExact(arena.allocateUtf8String("%d plus %d equals %d"), 2, 2, 4); //prints "2 plus 2 equals 4" 292 } 293 294 } 295 296 void downcallHandle() { 297 Linker linker = Linker.nativeLinker(); 298 FunctionDescriptor function = null; 299 MemorySegment symbol = null; 300 301 linker.downcallHandle(function).bindTo(symbol); 302 303 } 304 305 void captureCallState() throws Throwable { 306 307 MemorySegment targetAddress = null; // ... 308 Linker.Option ccs = Linker.Option.captureCallState("errno"); 309 MethodHandle handle = Linker.nativeLinker().downcallHandle(targetAddress, FunctionDescriptor.ofVoid(), ccs); 310 311 StructLayout capturedStateLayout = Linker.Option.captureStateLayout(); 312 VarHandle errnoHandle = capturedStateLayout.varHandle(PathElement.groupElement("errno")); 313 try (Arena arena = Arena.ofConfined()) { 314 MemorySegment capturedState = arena.allocate(capturedStateLayout); 315 handle.invoke(capturedState); 316 int errno = (int) errnoHandle.get(capturedState); 317 // use errno 318 } 319 } 320 321 void captureStateLayout() { 322 String capturedNames = Linker.Option.captureStateLayout().memberLayouts().stream() 323 .map(MemoryLayout::name) 324 .flatMap(Optional::stream) 325 .map(Objects::toString) 326 .collect(Collectors.joining(", ")); 327 } 328 329 330 } 331 332 static class MemoryLayoutSnippets { 333 334 void header() throws Throwable { 335 SequenceLayout taggedValues = sequenceLayout(5, 336 structLayout( 337 ValueLayout.JAVA_BYTE.withName("kind"), 338 MemoryLayout.paddingLayout(24), 339 ValueLayout.JAVA_INT.withName("value") 340 ) 341 ).withName("TaggedValues"); 342 343 long valueOffset = taggedValues.byteOffset(PathElement.sequenceElement(0), 344 PathElement.groupElement("value")); // yields 4 345 346 MemoryLayout value = taggedValues.select(PathElement.sequenceElement(), 347 PathElement.groupElement("value")); 348 349 VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(), 350 PathElement.groupElement("value")); 351 352 MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(), 353 PathElement.groupElement("kind")); 354 long offset1 = (long) offsetHandle.invokeExact(1L); // 8 355 long offset2 = (long) offsetHandle.invokeExact(2L); // 16 356 } 357 358 void sliceHandle() { 359 MemorySegment segment = null; 360 long offset = 0; 361 MemoryLayout layout = null; 362 363 segment.asSlice(offset, layout.byteSize()); 364 } 365 366 void sequenceLayout0() { 367 MemoryLayout elementLayout = JAVA_INT; 368 369 sequenceLayout(Long.MAX_VALUE / elementLayout.byteSize(), elementLayout); 370 } 371 372 void structLayout0() { 373 MemoryLayout elementLayout = JAVA_INT; 374 375 structLayout(JAVA_SHORT, JAVA_INT); 376 structLayout(JAVA_SHORT, MemoryLayout.paddingLayout(16), JAVA_INT); 377 structLayout(JAVA_SHORT, JAVA_INT.withByteAlignment(2)); 378 } 379 380 } 381 382 static class MemorySegmentSnippets { 383 void header() throws NoSuchMethodException, IllegalAccessException { 384 385 { 386 MemorySegment segment = null; // ... 387 int value = segment.get(ValueLayout.JAVA_INT, 0); 388 } 389 390 { 391 MemorySegment segment = null; // ... 392 393 int value = segment.get(ValueLayout.JAVA_INT.withOrder(BIG_ENDIAN), 0); 394 } 395 396 { 397 MemorySegment segment = null; // ... 398 399 VarHandle intHandle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT); 400 MethodHandle multiplyExact = MethodHandles.lookup() 401 .findStatic(Math.class, "multiplyExact", 402 MethodType.methodType(long.class, long.class, long.class)); 403 intHandle = MethodHandles.filterCoordinates(intHandle, 1, 404 MethodHandles.insertArguments(multiplyExact, 0, ValueLayout.JAVA_INT.byteSize())); 405 int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12 406 } 407 408 { 409 MemorySegment segment = null; // ... 410 411 VarHandle intHandle = ValueLayout.JAVA_INT.arrayElementVarHandle(); 412 int value = (int) intHandle.get(segment, 3L); // get int element at offset 3 * 4 = 12 413 } 414 415 { 416 Arena arena = Arena.ofConfined(); 417 MemorySegment segment = arena.allocate(100); 418 MemorySegment slice = segment.asSlice(50, 10); 419 slice.get(ValueLayout.JAVA_INT, 20); // Out of bounds! 420 arena.close(); 421 slice.get(ValueLayout.JAVA_INT, 0); // Already closed! 422 } 423 424 425 { 426 try (Arena arena = Arena.ofShared()) { 427 SequenceLayout SEQUENCE_LAYOUT = MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT); 428 MemorySegment segment = arena.allocate(SEQUENCE_LAYOUT); 429 int sum = segment.elements(ValueLayout.JAVA_INT).parallel() 430 .mapToInt(s -> s.get(ValueLayout.JAVA_INT, 0)) 431 .sum(); 432 } 433 } 434 435 { 436 MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]); 437 byteSegment.get(ValueLayout.JAVA_INT, 0); // fails: layout alignment is 4, segment max alignment is 1 438 } 439 440 { 441 MemorySegment longSegment = MemorySegment.ofArray(new long[10]); 442 longSegment.get(ValueLayout.JAVA_INT, 0); // ok: layout alignment is 4, segment max alignment is 8 443 } 444 445 { 446 MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]); 447 byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: layout alignment is 1, segment max alignment is 1 448 } 449 450 { 451 MemorySegment segment = null; 452 long offset = 42; 453 454 MemorySegment z = segment.get(ValueLayout.ADDRESS, offset); // size = 0 455 MemorySegment ptr = z.reinterpret(16); // size = 16 456 int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 457 } 458 459 { 460 MemorySegment segment = null; 461 long offset = 42; 462 463 MemorySegment ptr = null; 464 try (Arena arena = Arena.ofConfined()) { 465 MemorySegment z = segment.get(ValueLayout.ADDRESS, offset); // size = 0, scope = always alive 466 ptr = z.reinterpret(16, arena, null); // size = 4, scope = arena.scope() 467 int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 468 } 469 int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // throws IllegalStateException 470 } 471 472 { 473 MemorySegment segment = null; 474 long offset = 42; 475 476 AddressLayout intArrPtrLayout = ValueLayout.ADDRESS.withTargetLayout( 477 MemoryLayout.sequenceLayout(4, ValueLayout.JAVA_INT)); // layout for int (*ptr)[4] 478 MemorySegment ptr = segment.get(intArrPtrLayout, offset); // size = 16 479 int x = ptr.getAtIndex(ValueLayout.JAVA_INT, 3); // ok 480 } 481 482 483 } 484 485 boolean isAligned(MemorySegment segment, long offset, MemoryLayout layout) { 486 return ((segment.address() + offset) % layout.byteAlignment()) == 0; 487 } 488 489 void elements() { 490 MemorySegment segment = null; 491 MemoryLayout elementLayout = JAVA_INT; 492 493 StreamSupport.stream(segment.spliterator(elementLayout), false); 494 } 495 496 void asSlice() { 497 MemorySegment segment = null; 498 long offset = 42; 499 MemoryLayout layout = JAVA_INT; 500 501 segment.asSlice(offset, layout.byteSize(), 1); 502 503 segment.asSlice(offset, layout.byteSize(), layout.byteAlignment()); 504 505 segment.asSlice(offset, segment.byteSize() - offset); 506 507 } 508 509 void reinterpret() { 510 MemorySegment segment = null; 511 512 MemorySegment cleanupSegment = MemorySegment.ofAddress(segment.address()); 513 514 } 515 516 void segmentOffset() { 517 MemorySegment segment = null; 518 MemorySegment other = null; 519 520 long offset = other.address() - segment.address(); 521 } 522 523 void fill() { 524 MemorySegment segment = null; 525 byte value = 42; 526 527 var byteHandle = MemoryLayout.sequenceLayout(ValueLayout.JAVA_BYTE) 528 .varHandle(MemoryLayout.PathElement.sequenceElement()); 529 for (long l = 0; l < segment.byteSize(); l++) { 530 byteHandle.set(segment.address(), l, value); 531 } 532 } 533 534 void copyFrom() { 535 MemorySegment src = null; 536 MemorySegment dst = null; 537 538 // MemorySegment.copy(src, 0, this, 0, src.byteSize()); 539 MemorySegment.copy(src, 0, dst, 0, src.byteSize()); 540 } 541 542 void copy() { 543 MemorySegment srcSegment = null; 544 long srcOffset = 42; 545 MemorySegment dstSegment = null; 546 long dstOffset = 13; 547 long bytes = 3; 548 549 MemorySegment.copy(srcSegment, ValueLayout.JAVA_BYTE, srcOffset, dstSegment, ValueLayout.JAVA_BYTE, dstOffset, bytes); 550 } 551 552 553 } 554 555 static class PackageInfoSnippets { 556 557 void header() throws Throwable { 558 try (Arena arena = Arena.ofConfined()) { 559 MemorySegment segment = arena.allocate(10 * 4); 560 for (int i = 0; i < 10; i++) { 561 segment.setAtIndex(ValueLayout.JAVA_INT, i, i); 562 } 563 } 564 565 Linker linker = Linker.nativeLinker(); 566 SymbolLookup stdlib = linker.defaultLookup(); 567 MethodHandle strlen = linker.downcallHandle( 568 stdlib.find("strlen").orElseThrow(), 569 FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS) 570 ); 571 572 try (Arena arena = Arena.ofConfined()) { 573 MemorySegment cString = arena.allocateUtf8String("Hello"); 574 long len = (long) strlen.invokeExact(cString); // 5 575 } 576 577 } 578 } 579 580 static class PaddingLayoutSnippets { 581 } 582 583 static class SegmentAllocatorSnippets { 584 void prefixAllocator() { 585 MemorySegment segment = null; //... 586 SegmentAllocator prefixAllocator = (size, align) -> segment.asSlice(0, size); 587 } 588 589 } 590 591 static class SequenceLayoutSnippets { 592 void header() { 593 MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); 594 595 MemoryLayout.structLayout( 596 ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), 597 ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN), 598 ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); 599 600 } 601 602 void reshape() { 603 var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT)); 604 var reshapeSeq = MemoryLayout.sequenceLayout(2, MemoryLayout.sequenceLayout(6, ValueLayout.JAVA_INT)); 605 606 var reshapeSeqImplicit1 = seq.reshape(-1, 6); 607 var reshapeSeqImplicit2 = seq.reshape(2, -1); 608 609 } 610 611 void flatten() { 612 var seq = MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT)); 613 var flattenedSeq = MemoryLayout.sequenceLayout(12, ValueLayout.JAVA_INT); 614 } 615 616 } 617 618 static class StructLayoutSnippets { 619 } 620 621 static class SymbolLookupSnippets { 622 623 void header() { 624 try (Arena arena = Arena.ofConfined()) { 625 SymbolLookup libGL = libraryLookup("libGL.so", arena); // libGL.so loaded here 626 MemorySegment glGetString = libGL.find("glGetString").orElseThrow(); 627 // ... 628 } // libGL.so unloaded here 629 630 System.loadLibrary("GL"); // libGL.so loaded here 631 // ... 632 SymbolLookup libGL = loaderLookup(); 633 MemorySegment glGetString = libGL.find("glGetString").orElseThrow(); 634 635 636 Arena arena = Arena.ofAuto(); 637 638 639 libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true 640 loaderLookup().find("glGetString").isPresent(); // false 641 642 libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true 643 loaderLookup().find("glGetString").isPresent(); // false 644 645 Linker nativeLinker = Linker.nativeLinker(); 646 SymbolLookup stdlib = nativeLinker.defaultLookup(); 647 MemorySegment malloc = stdlib.find("malloc").orElseThrow(); 648 } 649 650 } 651 652 static class UnionLayoutSnippets { 653 } 654 655 static class ValueLayoutSnippets { 656 657 void arrayElementVarHandle() { 658 VarHandle arrayHandle = ValueLayout.JAVA_INT.arrayElementVarHandle(10, 20); 659 660 SequenceLayout arrayLayout = MemoryLayout.sequenceLayout( 661 MemoryLayout.sequenceLayout(10, 662 MemoryLayout.sequenceLayout(20, ValueLayout.JAVA_INT))); 663 664 int value1 = (int) arrayHandle.get(10, 2, 4); // ok, accessed offset = 8176 665 int value2 = (int) arrayHandle.get(0, 0, 30); // out of bounds value for z 666 } 667 668 void statics() { 669 ADDRESS.withByteAlignment(1); 670 JAVA_CHAR.withByteAlignment(1); 671 JAVA_SHORT.withByteAlignment(1); 672 JAVA_INT.withByteAlignment(1); 673 JAVA_LONG.withByteAlignment(1); 674 JAVA_FLOAT.withByteAlignment(1); 675 JAVA_DOUBLE.withByteAlignment(1); 676 } 677 678 } 679 680 }