< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/windows/WinVaList.java

Print this page
*** 24,11 ***
   *
   */
  package jdk.internal.foreign.abi.x64.windows;
  
  import jdk.incubator.foreign.*;
! import jdk.incubator.foreign.CLinker.VaList;
  import jdk.internal.foreign.ResourceScopeImpl;
  import jdk.internal.foreign.abi.SharedUtils;
  import jdk.internal.foreign.abi.SharedUtils.SimpleVaArg;
  
  import java.lang.invoke.VarHandle;
--- 24,11 ---
   *
   */
  package jdk.internal.foreign.abi.x64.windows;
  
  import jdk.incubator.foreign.*;
! import jdk.internal.foreign.Scoped;
  import jdk.internal.foreign.ResourceScopeImpl;
  import jdk.internal.foreign.abi.SharedUtils;
  import jdk.internal.foreign.abi.SharedUtils.SimpleVaArg;
  
  import java.lang.invoke.VarHandle;

*** 53,14 ***
  //    #define __crt_va_arg(ap, t)                                               \
  //        ((sizeof(t) > sizeof(__int64) || (sizeof(t) & (sizeof(t) - 1)) != 0) \
  //            ? **(t**)((ap += sizeof(__int64)) - sizeof(__int64))             \
  //            :  *(t* )((ap += sizeof(__int64)) - sizeof(__int64)))
  //
! public non-sealed class WinVaList implements VaList {
      public static final Class<?> CARRIER = MemoryAddress.class;
      private static final long VA_SLOT_SIZE_BYTES = 8;
!     private static final VarHandle VH_address = MemoryHandles.asAddressVarHandle(C_POINTER.varHandle(long.class));
  
      private static final VaList EMPTY = new SharedUtils.EmptyVaList(MemoryAddress.NULL);
  
      private MemorySegment segment;
      private final ResourceScope scope;
--- 53,14 ---
  //    #define __crt_va_arg(ap, t)                                               \
  //        ((sizeof(t) > sizeof(__int64) || (sizeof(t) & (sizeof(t) - 1)) != 0) \
  //            ? **(t**)((ap += sizeof(__int64)) - sizeof(__int64))             \
  //            :  *(t* )((ap += sizeof(__int64)) - sizeof(__int64)))
  //
! public non-sealed class WinVaList implements VaList, Scoped {
      public static final Class<?> CARRIER = MemoryAddress.class;
      private static final long VA_SLOT_SIZE_BYTES = 8;
!     private static final VarHandle VH_address = C_POINTER.varHandle();
  
      private static final VaList EMPTY = new SharedUtils.EmptyVaList(MemoryAddress.NULL);
  
      private MemorySegment segment;
      private final ResourceScope scope;

*** 73,82 ***
      public static final VaList empty() {
          return EMPTY;
      }
  
      @Override
!     public int vargAsInt(MemoryLayout layout) {
          return (int) read(int.class, layout);
      }
  
      @Override
!     public long vargAsLong(MemoryLayout layout) {
          return (long) read(long.class, layout);
      }
  
      @Override
!     public double vargAsDouble(MemoryLayout layout) {
          return (double) read(double.class, layout);
      }
  
      @Override
!     public MemoryAddress vargAsAddress(MemoryLayout layout) {
          return (MemoryAddress) read(MemoryAddress.class, layout);
      }
  
      @Override
!     public MemorySegment vargAsSegment(MemoryLayout layout, SegmentAllocator allocator) {
          Objects.requireNonNull(allocator);
          return (MemorySegment) read(MemorySegment.class, layout, allocator);
      }
  
-     @Override
-     public MemorySegment vargAsSegment(MemoryLayout layout, ResourceScope scope) {
-         return vargAsSegment(layout, SegmentAllocator.ofScope(scope));
-     }
- 
      private Object read(Class<?> carrier, MemoryLayout layout) {
          return read(carrier, layout, SharedUtils.THROWING_ALLOCATOR);
      }
  
      private Object read(Class<?> carrier, MemoryLayout layout, SegmentAllocator allocator) {
          Objects.requireNonNull(layout);
-         SharedUtils.checkCompatibleType(carrier, layout, Windowsx64Linker.ADDRESS_SIZE);
          Object res;
          if (carrier == MemorySegment.class) {
!             TypeClass typeClass = TypeClass.typeClassFor(layout);
              res = switch (typeClass) {
                  case STRUCT_REFERENCE -> {
                      MemoryAddress structAddr = (MemoryAddress) VH_address.get(segment);
!                     MemorySegment struct = structAddr.asSegment(layout.byteSize(), scope());
                      MemorySegment seg = allocator.allocate(layout);
                      seg.copyFrom(struct);
                      yield seg;
                  }
!                 case STRUCT_REGISTER -> {
!                     MemorySegment struct = allocator.allocate(layout);
-                     struct.copyFrom(segment.asSlice(0L, layout.byteSize()));
-                     yield struct;
-                 }
                  default -> throw new IllegalStateException("Unexpected TypeClass: " + typeClass);
              };
          } else {
!             VarHandle reader = SharedUtils.vhPrimitiveOrAddress(carrier, layout);
              res = reader.get(segment);
          }
          segment = segment.asSlice(VA_SLOT_SIZE_BYTES);
          return res;
      }
  
      @Override
      public void skip(MemoryLayout... layouts) {
          Objects.requireNonNull(layouts);
          Stream.of(layouts).forEach(Objects::requireNonNull);
          segment = segment.asSlice(layouts.length * VA_SLOT_SIZE_BYTES);
      }
  
      static WinVaList ofAddress(MemoryAddress addr, ResourceScope scope) {
!         MemorySegment segment = addr.asSegment(Long.MAX_VALUE, scope);
          return new WinVaList(segment, scope);
      }
  
      static Builder builder(ResourceScope scope) {
          return new Builder(scope);
--- 73,74 ---
      public static final VaList empty() {
          return EMPTY;
      }
  
      @Override
!     public int nextVarg(ValueLayout.OfInt layout) {
          return (int) read(int.class, layout);
      }
  
      @Override
!     public long nextVarg(ValueLayout.OfLong layout) {
          return (long) read(long.class, layout);
      }
  
      @Override
!     public double nextVarg(ValueLayout.OfDouble layout) {
          return (double) read(double.class, layout);
      }
  
      @Override
!     public MemoryAddress nextVarg(ValueLayout.OfAddress layout) {
          return (MemoryAddress) read(MemoryAddress.class, layout);
      }
  
      @Override
!     public MemorySegment nextVarg(GroupLayout layout, SegmentAllocator allocator) {
          Objects.requireNonNull(allocator);
          return (MemorySegment) read(MemorySegment.class, layout, allocator);
      }
  
      private Object read(Class<?> carrier, MemoryLayout layout) {
          return read(carrier, layout, SharedUtils.THROWING_ALLOCATOR);
      }
  
      private Object read(Class<?> carrier, MemoryLayout layout, SegmentAllocator allocator) {
          Objects.requireNonNull(layout);
          Object res;
          if (carrier == MemorySegment.class) {
!             TypeClass typeClass = TypeClass.typeClassFor(layout, false);
              res = switch (typeClass) {
                  case STRUCT_REFERENCE -> {
                      MemoryAddress structAddr = (MemoryAddress) VH_address.get(segment);
!                     MemorySegment struct = MemorySegment.ofAddressNative(structAddr, layout.byteSize(), scope());
                      MemorySegment seg = allocator.allocate(layout);
                      seg.copyFrom(struct);
                      yield seg;
                  }
!                 case STRUCT_REGISTER ->
!                     allocator.allocate(layout).copyFrom(segment.asSlice(0, layout.byteSize()));
                  default -> throw new IllegalStateException("Unexpected TypeClass: " + typeClass);
              };
          } else {
!             VarHandle reader = layout.varHandle();
              res = reader.get(segment);
          }
          segment = segment.asSlice(VA_SLOT_SIZE_BYTES);
          return res;
      }
  
      @Override
      public void skip(MemoryLayout... layouts) {
          Objects.requireNonNull(layouts);
+         ((ResourceScopeImpl)scope).checkValidStateSlow();
          Stream.of(layouts).forEach(Objects::requireNonNull);
          segment = segment.asSlice(layouts.length * VA_SLOT_SIZE_BYTES);
      }
  
      static WinVaList ofAddress(MemoryAddress addr, ResourceScope scope) {
!         MemorySegment segment = MemorySegment.ofAddressNative(addr, Long.MAX_VALUE, scope);
          return new WinVaList(segment, scope);
      }
  
      static Builder builder(ResourceScope scope) {
          return new Builder(scope);

*** 181,65 ***
          }
  
          private Builder arg(Class<?> carrier, MemoryLayout layout, Object value) {
              Objects.requireNonNull(layout);
              Objects.requireNonNull(value);
-             SharedUtils.checkCompatibleType(carrier, layout, Windowsx64Linker.ADDRESS_SIZE);
              args.add(new SimpleVaArg(carrier, layout, value));
              return this;
          }
  
          @Override
!         public Builder vargFromInt(ValueLayout layout, int value) {
              return arg(int.class, layout, value);
          }
  
          @Override
!         public Builder vargFromLong(ValueLayout layout, long value) {
              return arg(long.class, layout, value);
          }
  
          @Override
!         public Builder vargFromDouble(ValueLayout layout, double value) {
              return arg(double.class, layout, value);
          }
  
          @Override
!         public Builder vargFromAddress(ValueLayout layout, Addressable value) {
              return arg(MemoryAddress.class, layout, value.address());
          }
  
          @Override
!         public Builder vargFromSegment(GroupLayout layout, MemorySegment value) {
              return arg(MemorySegment.class, layout, value);
          }
  
          public VaList build() {
              if (args.isEmpty()) {
                  return EMPTY;
              }
!             SegmentAllocator allocator = SegmentAllocator.arenaAllocator(scope);
              MemorySegment segment = allocator.allocate(VA_SLOT_SIZE_BYTES * args.size());
              List<MemorySegment> attachedSegments = new ArrayList<>();
              attachedSegments.add(segment);
              MemorySegment cursor = segment;
  
              for (SimpleVaArg arg : args) {
                  if (arg.carrier == MemorySegment.class) {
                      MemorySegment msArg = ((MemorySegment) arg.value);
!                     TypeClass typeClass = TypeClass.typeClassFor(arg.layout);
                      switch (typeClass) {
                          case STRUCT_REFERENCE -> {
                              MemorySegment copy = allocator.allocate(arg.layout);
                              copy.copyFrom(msArg); // by-value
                              attachedSegments.add(copy);
                              VH_address.set(cursor, copy.address());
                          }
!                         case STRUCT_REGISTER -> {
!                             MemorySegment slice = cursor.asSlice(0, VA_SLOT_SIZE_BYTES);
-                             slice.copyFrom(msArg);
-                         }
                          default -> throw new IllegalStateException("Unexpected TypeClass: " + typeClass);
                      }
                  } else {
                      VarHandle writer = arg.varHandle();
                      writer.set(cursor, arg.value);
--- 173,62 ---
          }
  
          private Builder arg(Class<?> carrier, MemoryLayout layout, Object value) {
              Objects.requireNonNull(layout);
              Objects.requireNonNull(value);
              args.add(new SimpleVaArg(carrier, layout, value));
              return this;
          }
  
          @Override
!         public Builder addVarg(ValueLayout.OfInt layout, int value) {
              return arg(int.class, layout, value);
          }
  
          @Override
!         public Builder addVarg(ValueLayout.OfLong layout, long value) {
              return arg(long.class, layout, value);
          }
  
          @Override
!         public Builder addVarg(ValueLayout.OfDouble layout, double value) {
              return arg(double.class, layout, value);
          }
  
          @Override
!         public Builder addVarg(ValueLayout.OfAddress layout, Addressable value) {
              return arg(MemoryAddress.class, layout, value.address());
          }
  
          @Override
!         public Builder addVarg(GroupLayout layout, MemorySegment value) {
              return arg(MemorySegment.class, layout, value);
          }
  
          public VaList build() {
              if (args.isEmpty()) {
                  return EMPTY;
              }
!             SegmentAllocator allocator = SegmentAllocator.newNativeArena(scope);
              MemorySegment segment = allocator.allocate(VA_SLOT_SIZE_BYTES * args.size());
              List<MemorySegment> attachedSegments = new ArrayList<>();
              attachedSegments.add(segment);
              MemorySegment cursor = segment;
  
              for (SimpleVaArg arg : args) {
                  if (arg.carrier == MemorySegment.class) {
                      MemorySegment msArg = ((MemorySegment) arg.value);
!                     TypeClass typeClass = TypeClass.typeClassFor(arg.layout, false);
                      switch (typeClass) {
                          case STRUCT_REFERENCE -> {
                              MemorySegment copy = allocator.allocate(arg.layout);
                              copy.copyFrom(msArg); // by-value
                              attachedSegments.add(copy);
                              VH_address.set(cursor, copy.address());
                          }
!                         case STRUCT_REGISTER ->
!                             cursor.copyFrom(msArg.asSlice(0, VA_SLOT_SIZE_BYTES));
                          default -> throw new IllegalStateException("Unexpected TypeClass: " + typeClass);
                      }
                  } else {
                      VarHandle writer = arg.varHandle();
                      writer.set(cursor, arg.value);
< prev index next >