< prev index next >

test/jdk/java/foreign/CallGeneratorHelper.java

Print this page

  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 import jdk.incubator.foreign.GroupLayout;
 26 import jdk.incubator.foreign.MemoryAddress;
 27 import jdk.incubator.foreign.MemoryLayout;
 28 import jdk.incubator.foreign.MemorySegment;

 29 import jdk.incubator.foreign.ResourceScope;
 30 import jdk.incubator.foreign.SegmentAllocator;
 31 import jdk.incubator.foreign.ValueLayout;
 32 

 33 import java.lang.invoke.VarHandle;
 34 import java.util.ArrayList;
 35 import java.util.List;
 36 import java.util.Stack;
 37 import java.util.function.Consumer;
 38 import java.util.stream.Collectors;
 39 import java.util.stream.IntStream;

 40 
 41 import org.testng.annotations.*;
 42 
 43 import static jdk.incubator.foreign.CLinker.*;
 44 import static org.testng.Assert.*;
 45 
 46 public class CallGeneratorHelper extends NativeTestHelper {
 47 
 48     static SegmentAllocator IMPLICIT_ALLOCATOR = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());







 49 
 50     static final int SAMPLE_FACTOR = Integer.parseInt((String)System.getProperties().getOrDefault("generator.sample.factor", "-1"));
 51 
 52     static final int MAX_FIELDS = 3;
 53     static final int MAX_PARAMS = 3;
 54     static final int CHUNK_SIZE = 600;
 55 
 56     public static void assertStructEquals(MemorySegment actual, MemorySegment expected, MemoryLayout layout) {
 57         assertEquals(actual.byteSize(), expected.byteSize());
 58         GroupLayout g = (GroupLayout) layout;
 59         for (MemoryLayout field : g.memberLayouts()) {
 60             if (field instanceof ValueLayout) {
 61                 VarHandle vh = g.varHandle(vhCarrier(field), MemoryLayout.PathElement.groupElement(field.name().orElseThrow()));
 62                 assertEquals(vh.get(actual), vh.get(expected));
 63             }
 64         }
 65     }
 66 
 67     private static Class<?> vhCarrier(MemoryLayout layout) {
 68         if (layout instanceof ValueLayout) {
 69             if (isIntegral(layout)) {
 70                 if (layout.bitSize() == 64) {
 71                     return long.class;
 72                 }
 73                 return int.class;
 74             } else if (layout.bitSize() == 32) {
 75                 return float.class;
 76             }
 77             return double.class;
 78         } else {
 79             throw new IllegalStateException("Unexpected layout: " + layout);
 80         }
 81     }

393                 return 42;
394             } else if (layout.bitSize() == 32) {
395                 if (check) {
396                     checks.add(o -> assertEquals(o, 12f));
397                 }
398                 return 12f;
399             } else {
400                 if (check) {
401                     checks.add(o -> assertEquals(o, 24d));
402                 }
403                 return 24d;
404             }
405         } else {
406             throw new IllegalStateException("Unexpected layout: " + layout);
407         }
408     }
409 
410     static void initStruct(MemorySegment str, GroupLayout g, List<Consumer<Object>> checks, boolean check) throws ReflectiveOperationException {
411         for (MemoryLayout l : g.memberLayouts()) {
412             if (l.isPadding()) continue;
413             VarHandle accessor = g.varHandle(structFieldCarrier(l), MemoryLayout.PathElement.groupElement(l.name().get()));
414             List<Consumer<Object>> fieldsCheck = new ArrayList<>();
415             Object value = makeArg(l, fieldsCheck, check);
416             if (isPointer(l)) {
417                 value = ((MemoryAddress)value).toRawLongValue();
418             }
419             //set value
420             accessor.set(str, value);
421             //add check
422             if (check) {
423                 assertTrue(fieldsCheck.size() == 1);
424                 checks.add(o -> {
425                     MemorySegment actual = (MemorySegment)o;
426                     try {
427                         if (isPointer(l)) {
428                             fieldsCheck.get(0).accept(MemoryAddress.ofLong((long)accessor.get(actual)));
429                         } else {
430                             fieldsCheck.get(0).accept(accessor.get(actual));
431                         }
432                     } catch (Throwable ex) {
433                         throw new IllegalStateException(ex);
434                     }
435                 });
436             }
437         }
438     }
439 
440     static Class<?> structFieldCarrier(MemoryLayout layout) {
441         if (isPointer(layout)) {
442             return long.class;
443         } else if (layout instanceof ValueLayout) {
444             if (isIntegral(layout)) {
445                 return int.class;
446             } else if (layout.bitSize() == 32) {
447                 return float.class;
448             } else {
449                 return double.class;
450             }
451         } else {
452             throw new IllegalStateException("Unexpected layout: " + layout);
453         }
454     }
455 
456     static Class<?> paramCarrier(MemoryLayout layout) {
457         if (layout instanceof GroupLayout) {
458             return MemorySegment.class;
459         } if (isPointer(layout)) {
460             return MemoryAddress.class;
461         } else if (layout instanceof ValueLayout) {
462             if (isIntegral(layout)) {
463                 return int.class;
464             } else if (layout.bitSize() == 32) {
465                 return float.class;
466             } else {
467                 return double.class;
468             }
469         } else {
470             throw new IllegalStateException("Unexpected layout: " + layout);
471         }
472     }








473 }

  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 import jdk.incubator.foreign.Addressable;
 26 import jdk.incubator.foreign.CLinker;
 27 import jdk.incubator.foreign.FunctionDescriptor;
 28 import jdk.incubator.foreign.GroupLayout;
 29 import jdk.incubator.foreign.MemoryAddress;
 30 import jdk.incubator.foreign.MemoryLayout;
 31 import jdk.incubator.foreign.MemorySegment;
 32 import jdk.incubator.foreign.NativeSymbol;
 33 import jdk.incubator.foreign.ResourceScope;
 34 import jdk.incubator.foreign.SegmentAllocator;
 35 import jdk.incubator.foreign.ValueLayout;
 36 
 37 import java.lang.invoke.MethodHandle;
 38 import java.lang.invoke.VarHandle;
 39 import java.util.ArrayList;
 40 import java.util.List;
 41 import java.util.Stack;
 42 import java.util.function.Consumer;
 43 import java.util.stream.Collectors;
 44 import java.util.stream.IntStream;
 45 import java.util.stream.Stream;
 46 
 47 import org.testng.annotations.*;
 48 

 49 import static org.testng.Assert.*;
 50 
 51 public class CallGeneratorHelper extends NativeTestHelper {
 52 
 53     static final List<MemoryLayout> STACK_PREFIX_LAYOUTS = Stream.concat(
 54             Stream.generate(() -> (MemoryLayout) C_LONG_LONG).limit(8),
 55             Stream.generate(() -> (MemoryLayout)  C_DOUBLE).limit(8)
 56         ).toList();
 57 
 58     static SegmentAllocator THROWING_ALLOCATOR = (size, align) -> {
 59         throw new UnsupportedOperationException();
 60     };
 61 
 62     static final int SAMPLE_FACTOR = Integer.parseInt((String)System.getProperties().getOrDefault("generator.sample.factor", "-1"));
 63 
 64     static final int MAX_FIELDS = 3;
 65     static final int MAX_PARAMS = 3;
 66     static final int CHUNK_SIZE = 600;
 67 
 68     public static void assertStructEquals(MemorySegment actual, MemorySegment expected, MemoryLayout layout) {
 69         assertEquals(actual.byteSize(), expected.byteSize());
 70         GroupLayout g = (GroupLayout) layout;
 71         for (MemoryLayout field : g.memberLayouts()) {
 72             if (field instanceof ValueLayout) {
 73                 VarHandle vh = g.varHandle(MemoryLayout.PathElement.groupElement(field.name().orElseThrow()));
 74                 assertEquals(vh.get(actual), vh.get(expected));
 75             }
 76         }
 77     }
 78 
 79     private static Class<?> vhCarrier(MemoryLayout layout) {
 80         if (layout instanceof ValueLayout) {
 81             if (isIntegral(layout)) {
 82                 if (layout.bitSize() == 64) {
 83                     return long.class;
 84                 }
 85                 return int.class;
 86             } else if (layout.bitSize() == 32) {
 87                 return float.class;
 88             }
 89             return double.class;
 90         } else {
 91             throw new IllegalStateException("Unexpected layout: " + layout);
 92         }
 93     }

405                 return 42;
406             } else if (layout.bitSize() == 32) {
407                 if (check) {
408                     checks.add(o -> assertEquals(o, 12f));
409                 }
410                 return 12f;
411             } else {
412                 if (check) {
413                     checks.add(o -> assertEquals(o, 24d));
414                 }
415                 return 24d;
416             }
417         } else {
418             throw new IllegalStateException("Unexpected layout: " + layout);
419         }
420     }
421 
422     static void initStruct(MemorySegment str, GroupLayout g, List<Consumer<Object>> checks, boolean check) throws ReflectiveOperationException {
423         for (MemoryLayout l : g.memberLayouts()) {
424             if (l.isPadding()) continue;
425             VarHandle accessor = g.varHandle(MemoryLayout.PathElement.groupElement(l.name().get()));
426             List<Consumer<Object>> fieldsCheck = new ArrayList<>();
427             Object value = makeArg(l, fieldsCheck, check);



428             //set value
429             accessor.set(str, value);
430             //add check
431             if (check) {
432                 assertTrue(fieldsCheck.size() == 1);
433                 checks.add(o -> {
434                     MemorySegment actual = (MemorySegment)o;
435                     try {
436                         fieldsCheck.get(0).accept(accessor.get(actual));




437                     } catch (Throwable ex) {
438                         throw new IllegalStateException(ex);
439                     }
440                 });
441             }
442         }
443     }
444 
445     static Class<?> carrier(MemoryLayout layout, boolean param) {
















446         if (layout instanceof GroupLayout) {
447             return MemorySegment.class;
448         } if (isPointer(layout)) {
449             return param ? Addressable.class : MemoryAddress.class;
450         } else if (layout instanceof ValueLayout valueLayout) {
451             return valueLayout.carrier();






452         } else {
453             throw new IllegalStateException("Unexpected layout: " + layout);
454         }
455     }
456 
457     MethodHandle downcallHandle(CLinker abi, NativeSymbol symbol, SegmentAllocator allocator, FunctionDescriptor descriptor) {
458         MethodHandle mh = abi.downcallHandle(symbol, descriptor);
459         if (descriptor.returnLayout().isPresent() && descriptor.returnLayout().get() instanceof GroupLayout) {
460             mh = mh.bindTo(allocator);
461         }
462         return mh;
463     }
464 }
< prev index next >