< prev index next >

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

Print this page
*** 27,13 ***
  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.internal.foreign.Utils;
  import jdk.internal.foreign.abi.CallingSequenceBuilder;
- import jdk.internal.foreign.abi.UpcallHandler;
  import jdk.internal.foreign.abi.ABIDescriptor;
  import jdk.internal.foreign.abi.Binding;
  import jdk.internal.foreign.abi.CallingSequence;
  import jdk.internal.foreign.abi.ProgrammableInvoker;
  import jdk.internal.foreign.abi.ProgrammableUpcallHandler;
--- 27,14 ---
  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.internal.foreign.Utils;
  import jdk.internal.foreign.abi.CallingSequenceBuilder;
  import jdk.internal.foreign.abi.ABIDescriptor;
  import jdk.internal.foreign.abi.Binding;
  import jdk.internal.foreign.abi.CallingSequence;
  import jdk.internal.foreign.abi.ProgrammableInvoker;
  import jdk.internal.foreign.abi.ProgrammableUpcallHandler;

*** 80,43 ***
              this.isInMemoryReturn = isInMemoryReturn;
          }
      }
  
      public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) {
-         SharedUtils.checkFunctionTypes(mt, cDesc, Windowsx64Linker.ADDRESS_SIZE);
- 
          class CallingSequenceBuilderHelper {
              final CallingSequenceBuilder csb = new CallingSequenceBuilder(forUpcall);
              final BindingCalculator argCalc =
                  forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true);
              final BindingCalculator retCalc =
                  forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false);
  
!             void addArgumentBindings(Class<?> carrier, MemoryLayout layout) {
!                 csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout));
              }
  
              void setReturnBindings(Class<?> carrier, MemoryLayout layout) {
!                 csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout));
              }
          }
          var csb = new CallingSequenceBuilderHelper();
  
          boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout());
          if (returnInMemory) {
              Class<?> carrier = MemoryAddress.class;
              MemoryLayout layout = Win64.C_POINTER;
!             csb.addArgumentBindings(carrier, layout);
              if (forUpcall) {
                  csb.setReturnBindings(carrier, layout);
              }
          } else if (cDesc.returnLayout().isPresent()) {
              csb.setReturnBindings(mt.returnType(), cDesc.returnLayout().get());
          }
  
          for (int i = 0; i < mt.parameterCount(); i++) {
!             csb.addArgumentBindings(mt.parameterType(i), cDesc.argumentLayouts().get(i));
          }
  
          csb.csb.setTrivial(SharedUtils.isTrivial(cDesc));
  
          return new Bindings(csb.csb.build(), returnInMemory);
--- 81,41 ---
              this.isInMemoryReturn = isInMemoryReturn;
          }
      }
  
      public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) {
          class CallingSequenceBuilderHelper {
              final CallingSequenceBuilder csb = new CallingSequenceBuilder(forUpcall);
              final BindingCalculator argCalc =
                  forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true);
              final BindingCalculator retCalc =
                  forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false);
  
!             void addArgumentBindings(Class<?> carrier, MemoryLayout layout, boolean isVararg) {
!                 csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout, isVararg));
              }
  
              void setReturnBindings(Class<?> carrier, MemoryLayout layout) {
!                 csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout, false));
              }
          }
          var csb = new CallingSequenceBuilderHelper();
  
          boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout());
          if (returnInMemory) {
              Class<?> carrier = MemoryAddress.class;
              MemoryLayout layout = Win64.C_POINTER;
!             csb.addArgumentBindings(carrier, layout, false);
              if (forUpcall) {
                  csb.setReturnBindings(carrier, layout);
              }
          } else if (cDesc.returnLayout().isPresent()) {
              csb.setReturnBindings(mt.returnType(), cDesc.returnLayout().get());
          }
  
          for (int i = 0; i < mt.parameterCount(); i++) {
!             csb.addArgumentBindings(mt.parameterType(i), cDesc.argumentLayouts().get(i), SharedUtils.isVarargsIndex(cDesc, i));
          }
  
          csb.csb.setTrivial(SharedUtils.isTrivial(cDesc));
  
          return new Bindings(csb.csb.build(), returnInMemory);

*** 132,18 ***
          }
  
          return handle;
      }
  
!     public static UpcallHandler arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc) {
          Bindings bindings = getBindings(mt, cDesc, true);
  
          if (bindings.isInMemoryReturn) {
              target = SharedUtils.adaptUpcallForIMR(target, false /* need the return value as well */);
          }
  
!         return ProgrammableUpcallHandler.make(CWindows, target, bindings.callingSequence);
      }
  
      private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
          return returnLayout
                  .filter(GroupLayout.class::isInstance)
--- 131,18 ---
          }
  
          return handle;
      }
  
!     public static NativeSymbol arrangeUpcall(MethodHandle target, MethodType mt, FunctionDescriptor cDesc, ResourceScope scope) {
          Bindings bindings = getBindings(mt, cDesc, true);
  
          if (bindings.isInMemoryReturn) {
              target = SharedUtils.adaptUpcallForIMR(target, false /* need the return value as well */);
          }
  
!         return ProgrammableUpcallHandler.make(CWindows, target, bindings.callingSequence, scope);
      }
  
      private static boolean isInMemoryReturn(Optional<MemoryLayout> returnLayout) {
          return returnLayout
                  .filter(GroupLayout.class::isInstance)

*** 183,23 ***
              return CWindows.inputStorage[StorageClasses.INTEGER][nRegs - 1];
          }
      }
  
      private interface BindingCalculator {
!         List<Binding> getBindings(Class<?> carrier, MemoryLayout layout);
      }
  
      static class UnboxBindingCalculator implements BindingCalculator {
          private final StorageCalculator storageCalculator;
  
          UnboxBindingCalculator(boolean forArguments) {
              this.storageCalculator = new StorageCalculator(forArguments);
          }
  
          @Override
!         public List<Binding> getBindings(Class<?> carrier, MemoryLayout layout) {
!             TypeClass argumentClass = TypeClass.typeClassFor(layout);
              Binding.Builder bindings = Binding.builder();
              switch (argumentClass) {
                  case STRUCT_REGISTER: {
                      assert carrier == MemorySegment.class;
                      VMStorage storage = storageCalculator.nextStorage(StorageClasses.INTEGER, layout);
--- 182,23 ---
              return CWindows.inputStorage[StorageClasses.INTEGER][nRegs - 1];
          }
      }
  
      private interface BindingCalculator {
!         List<Binding> getBindings(Class<?> carrier, MemoryLayout layout, boolean isVararg);
      }
  
      static class UnboxBindingCalculator implements BindingCalculator {
          private final StorageCalculator storageCalculator;
  
          UnboxBindingCalculator(boolean forArguments) {
              this.storageCalculator = new StorageCalculator(forArguments);
          }
  
          @Override
!         public List<Binding> getBindings(Class<?> carrier, MemoryLayout layout, boolean isVararg) {
!             TypeClass argumentClass = TypeClass.typeClassFor(layout, isVararg);
              Binding.Builder bindings = Binding.builder();
              switch (argumentClass) {
                  case STRUCT_REGISTER: {
                      assert carrier == MemorySegment.class;
                      VMStorage storage = storageCalculator.nextStorage(StorageClasses.INTEGER, layout);

*** 209,18 ***
                      break;
                  }
                  case STRUCT_REFERENCE: {
                      assert carrier == MemorySegment.class;
                      bindings.copy(layout)
!                             .baseAddress()
-                             .unboxAddress();
                      VMStorage storage = storageCalculator.nextStorage(StorageClasses.INTEGER, layout);
                      bindings.vmStore(storage, long.class);
                      break;
                  }
                  case POINTER: {
!                     bindings.unboxAddress();
                      VMStorage storage = storageCalculator.nextStorage(StorageClasses.INTEGER, layout);
                      bindings.vmStore(storage, long.class);
                      break;
                  }
                  case INTEGER: {
--- 208,17 ---
                      break;
                  }
                  case STRUCT_REFERENCE: {
                      assert carrier == MemorySegment.class;
                      bindings.copy(layout)
!                             .unboxAddress(MemorySegment.class);
                      VMStorage storage = storageCalculator.nextStorage(StorageClasses.INTEGER, layout);
                      bindings.vmStore(storage, long.class);
                      break;
                  }
                  case POINTER: {
!                     bindings.unboxAddress(carrier);
                      VMStorage storage = storageCalculator.nextStorage(StorageClasses.INTEGER, layout);
                      bindings.vmStore(storage, long.class);
                      break;
                  }
                  case INTEGER: {

*** 257,12 ***
          BoxBindingCalculator(boolean forArguments) {
              this.storageCalculator = new StorageCalculator(forArguments);
          }
  
          @Override
!         public List<Binding> getBindings(Class<?> carrier, MemoryLayout layout) {
!             TypeClass argumentClass = TypeClass.typeClassFor(layout);
              Binding.Builder bindings = Binding.builder();
              switch (argumentClass) {
                  case STRUCT_REGISTER: {
                      assert carrier == MemorySegment.class;
                      bindings.allocate(layout)
--- 255,12 ---
          BoxBindingCalculator(boolean forArguments) {
              this.storageCalculator = new StorageCalculator(forArguments);
          }
  
          @Override
!         public List<Binding> getBindings(Class<?> carrier, MemoryLayout layout, boolean isVararg) {
!             TypeClass argumentClass = TypeClass.typeClassFor(layout, isVararg);
              Binding.Builder bindings = Binding.builder();
              switch (argumentClass) {
                  case STRUCT_REGISTER: {
                      assert carrier == MemorySegment.class;
                      bindings.allocate(layout)
< prev index next >