< prev index next >

test/jdk/java/foreign/CallGeneratorHelper.java

Print this page
@@ -20,34 +20,46 @@
   *  or visit www.oracle.com if you need additional information or have any
   *  questions.
   *
   */
  
+ import jdk.incubator.foreign.Addressable;
+ import jdk.incubator.foreign.CLinker;
+ import jdk.incubator.foreign.FunctionDescriptor;
  import jdk.incubator.foreign.GroupLayout;
  import jdk.incubator.foreign.MemoryAddress;
  import jdk.incubator.foreign.MemoryLayout;
  import jdk.incubator.foreign.MemorySegment;
+ import jdk.incubator.foreign.NativeSymbol;
  import jdk.incubator.foreign.ResourceScope;
  import jdk.incubator.foreign.SegmentAllocator;
  import jdk.incubator.foreign.ValueLayout;
  
+ import java.lang.invoke.MethodHandle;
  import java.lang.invoke.VarHandle;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Stack;
  import java.util.function.Consumer;
  import java.util.stream.Collectors;
  import java.util.stream.IntStream;
+ import java.util.stream.Stream;
  
  import org.testng.annotations.*;
  
- import static jdk.incubator.foreign.CLinker.*;
  import static org.testng.Assert.*;
  
  public class CallGeneratorHelper extends NativeTestHelper {
  
-     static SegmentAllocator IMPLICIT_ALLOCATOR = (size, align) -> MemorySegment.allocateNative(size, align, ResourceScope.newImplicitScope());
+     static final List<MemoryLayout> STACK_PREFIX_LAYOUTS = Stream.concat(
+             Stream.generate(() -> (MemoryLayout) C_LONG_LONG).limit(8),
+             Stream.generate(() -> (MemoryLayout)  C_DOUBLE).limit(8)
+         ).toList();
+ 
+     static SegmentAllocator THROWING_ALLOCATOR = (size, align) -> {
+         throw new UnsupportedOperationException();
+     };
  
      static final int SAMPLE_FACTOR = Integer.parseInt((String)System.getProperties().getOrDefault("generator.sample.factor", "-1"));
  
      static final int MAX_FIELDS = 3;
      static final int MAX_PARAMS = 3;

@@ -56,11 +68,11 @@
      public static void assertStructEquals(MemorySegment actual, MemorySegment expected, MemoryLayout layout) {
          assertEquals(actual.byteSize(), expected.byteSize());
          GroupLayout g = (GroupLayout) layout;
          for (MemoryLayout field : g.memberLayouts()) {
              if (field instanceof ValueLayout) {
-                 VarHandle vh = g.varHandle(vhCarrier(field), MemoryLayout.PathElement.groupElement(field.name().orElseThrow()));
+                 VarHandle vh = g.varHandle(MemoryLayout.PathElement.groupElement(field.name().orElseThrow()));
                  assertEquals(vh.get(actual), vh.get(expected));
              }
          }
      }
  

@@ -408,66 +420,45 @@
      }
  
      static void initStruct(MemorySegment str, GroupLayout g, List<Consumer<Object>> checks, boolean check) throws ReflectiveOperationException {
          for (MemoryLayout l : g.memberLayouts()) {
              if (l.isPadding()) continue;
-             VarHandle accessor = g.varHandle(structFieldCarrier(l), MemoryLayout.PathElement.groupElement(l.name().get()));
+             VarHandle accessor = g.varHandle(MemoryLayout.PathElement.groupElement(l.name().get()));
              List<Consumer<Object>> fieldsCheck = new ArrayList<>();
              Object value = makeArg(l, fieldsCheck, check);
-             if (isPointer(l)) {
-                 value = ((MemoryAddress)value).toRawLongValue();
-             }
              //set value
              accessor.set(str, value);
              //add check
              if (check) {
                  assertTrue(fieldsCheck.size() == 1);
                  checks.add(o -> {
                      MemorySegment actual = (MemorySegment)o;
                      try {
-                         if (isPointer(l)) {
-                             fieldsCheck.get(0).accept(MemoryAddress.ofLong((long)accessor.get(actual)));
-                         } else {
-                             fieldsCheck.get(0).accept(accessor.get(actual));
-                         }
+                         fieldsCheck.get(0).accept(accessor.get(actual));
                      } catch (Throwable ex) {
                          throw new IllegalStateException(ex);
                      }
                  });
              }
          }
      }
  
-     static Class<?> structFieldCarrier(MemoryLayout layout) {
-         if (isPointer(layout)) {
-             return long.class;
-         } else if (layout instanceof ValueLayout) {
-             if (isIntegral(layout)) {
-                 return int.class;
-             } else if (layout.bitSize() == 32) {
-                 return float.class;
-             } else {
-                 return double.class;
-             }
-         } else {
-             throw new IllegalStateException("Unexpected layout: " + layout);
-         }
-     }
- 
-     static Class<?> paramCarrier(MemoryLayout layout) {
+     static Class<?> carrier(MemoryLayout layout, boolean param) {
          if (layout instanceof GroupLayout) {
              return MemorySegment.class;
          } if (isPointer(layout)) {
-             return MemoryAddress.class;
-         } else if (layout instanceof ValueLayout) {
-             if (isIntegral(layout)) {
-                 return int.class;
-             } else if (layout.bitSize() == 32) {
-                 return float.class;
-             } else {
-                 return double.class;
-             }
+             return param ? Addressable.class : MemoryAddress.class;
+         } else if (layout instanceof ValueLayout valueLayout) {
+             return valueLayout.carrier();
          } else {
              throw new IllegalStateException("Unexpected layout: " + layout);
          }
      }
+ 
+     MethodHandle downcallHandle(CLinker abi, NativeSymbol symbol, SegmentAllocator allocator, FunctionDescriptor descriptor) {
+         MethodHandle mh = abi.downcallHandle(symbol, descriptor);
+         if (descriptor.returnLayout().isPresent() && descriptor.returnLayout().get() instanceof GroupLayout) {
+             mh = mh.bindTo(allocator);
+         }
+         return mh;
+     }
  }
< prev index next >