1 /* 2 * Copyright (c) 2020, 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; 27 28 import java.lang.invoke.MethodHandle; 29 import java.lang.invoke.MethodType; 30 import java.util.Objects; 31 import java.util.Optional; 32 import java.util.List; 33 34 import jdk.internal.foreign.FunctionDescriptorImpl; 35 import jdk.internal.javac.PreviewFeature; 36 37 /** 38 * A function descriptor models the signature of a foreign function. A function descriptor is made up of zero or more 39 * argument layouts, and zero or one return layout. A function descriptor is used to create 40 * {@linkplain Linker#downcallHandle(MemorySegment, FunctionDescriptor, Linker.Option...) downcall method handles} and 41 * {@linkplain Linker#upcallStub(MethodHandle, FunctionDescriptor, Arena, Linker.Option...) upcall stubs}. 42 * 43 * @implSpec 44 * Implementing classes are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>. 45 * 46 * @see MemoryLayout 47 * @since 19 48 */ 49 @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN) 50 public sealed interface FunctionDescriptor permits FunctionDescriptorImpl { 51 52 /** 53 * {@return the return layout (if any) of this function descriptor} 54 */ 55 Optional<MemoryLayout> returnLayout(); 56 57 /** 58 * {@return the argument layouts of this function descriptor (as an unmodifiable list)}. 59 */ 60 List<MemoryLayout> argumentLayouts(); 61 62 /** 63 * Returns a function descriptor with the given argument layouts appended to the argument layouts 64 * of this function descriptor. 65 * @param addedLayouts the argument layouts to append. 66 * @throws IllegalArgumentException if one of the layouts in {@code addedLayouts} is a padding layout. 67 * @return a new function descriptor, with the provided additional argument layouts. 68 */ 69 FunctionDescriptor appendArgumentLayouts(MemoryLayout... addedLayouts); 70 71 /** 72 * Returns a function descriptor with the given argument layouts inserted at the given index, into the argument 73 * layout array of this function descriptor. 74 * @param index the index at which to insert the arguments 75 * @param addedLayouts the argument layouts to insert at given index. 76 * @return a new function descriptor, with the provided additional argument layouts. 77 * @throws IllegalArgumentException if one of the layouts in {@code addedLayouts} is a padding layout. 78 * @throws IllegalArgumentException if {@code index < 0 || index > argumentLayouts().size()}. 79 */ 80 FunctionDescriptor insertArgumentLayouts(int index, MemoryLayout... addedLayouts); 81 82 /** 83 * Returns a function descriptor with the provided return layout. 84 * @param newReturn the new return layout. 85 * @throws IllegalArgumentException if {@code newReturn} is a padding layout. 86 * @return a new function descriptor, with the provided return layout. 87 */ 88 FunctionDescriptor changeReturnLayout(MemoryLayout newReturn); 89 90 /** 91 * {@return a new function descriptor, with no return layout} 92 */ 93 FunctionDescriptor dropReturnLayout(); 94 95 /** 96 * Returns the method type consisting of the carrier types of the layouts in this function descriptor. 97 * <p> 98 * The carrier type of a layout {@code L} is determined as follows: 99 * <ul> 100 * <li>If {@code L} is a {@link ValueLayout} the carrier type is determined through {@link ValueLayout#carrier()}.</li> 101 * <li>If {@code L} is a {@link GroupLayout} or a {@link SequenceLayout}, the carrier type is {@link MemorySegment}.</li> 102 * </ul> 103 * 104 * @apiNote A function descriptor cannot, by construction, contain any padding layouts. As such, it is not 105 * necessary to specify how padding layout should be mapped to carrier types. 106 * 107 * @return the method type consisting of the carrier types of the layouts in this function descriptor. 108 */ 109 MethodType toMethodType(); 110 111 /** 112 * Creates a function descriptor with the given return and argument layouts. 113 * @param resLayout the return layout. 114 * @param argLayouts the argument layouts. 115 * @throws IllegalArgumentException if {@code resLayout} is a padding layout. 116 * @throws IllegalArgumentException if one of the layouts in {@code argLayouts} is a padding layout. 117 * @return a new function descriptor with the provided return and argument layouts. 118 */ 119 static FunctionDescriptor of(MemoryLayout resLayout, MemoryLayout... argLayouts) { 120 Objects.requireNonNull(resLayout); 121 // Null checks are implicit in List.of(argLayouts) 122 return FunctionDescriptorImpl.of(resLayout, List.of(argLayouts)); 123 } 124 125 /** 126 * Creates a function descriptor with the given argument layouts and no return layout. This is useful to model functions 127 * that return no values. 128 * @param argLayouts the argument layouts. 129 * @throws IllegalArgumentException if one of the layouts in {@code argLayouts} is a padding layout. 130 * @return a new function descriptor with the provided argument layouts. 131 */ 132 static FunctionDescriptor ofVoid(MemoryLayout... argLayouts) { 133 // Null checks are implicit in List.of(argLayouts) 134 return FunctionDescriptorImpl.ofVoid(List.of(argLayouts)); 135 } 136 }