|
31 | 31 | import jdk.internal.foreign.abi.SharedUtils; |
32 | 32 | import jdk.internal.javac.PreviewFeature; |
33 | 33 | import jdk.internal.reflect.CallerSensitive; |
34 | | -import jdk.internal.reflect.Reflection; |
35 | 34 |
|
36 | 35 | import java.lang.invoke.MethodHandle; |
37 | 36 | import java.nio.ByteOrder; |
| 37 | +import java.util.Map; |
38 | 38 | import java.util.Objects; |
39 | | -import java.util.Optional; |
40 | 39 | import java.util.Set; |
41 | 40 | import java.util.function.Consumer; |
42 | 41 | import java.util.stream.Collectors; |
|
59 | 58 | * <li>A linker allows foreign functions to call Java method handles, |
60 | 59 | * via the generation of {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, Arena, Option...) upcall stubs}.</li> |
61 | 60 | * </ul> |
| 61 | + * A linker provides a way to look up the <em>canonical layouts</em> associated with the data types used by the ABI. |
| 62 | + * For example, a linker implementing the C ABI might choose to provide a canonical layout for the C {@code size_t} |
| 63 | + * type. On 64-bit platforms, this canonical layout might be equal to {@link ValueLayout#JAVA_LONG}. The canonical |
| 64 | + * layouts supported by a linker are exposed via the {@link #canonicalLayouts()} method, which returns a map from |
| 65 | + * type names to canonical layouts. |
| 66 | + * <p> |
62 | 67 | * In addition, a linker provides a way to look up foreign functions in libraries that conform to the ABI. Each linker |
63 | 68 | * chooses a set of libraries that are commonly used on the OS and processor combination associated with the ABI. |
64 | 69 | * For example, a linker for Linux/x64 might choose two libraries: {@code libc} and {@code libm}. The functions in these |
|
103 | 108 | * defines the layouts associated with the parameter types and return type (if any) of the C function. |
104 | 109 | * <p> |
105 | 110 | * Scalar C types such as {@code bool}, {@code int} are modelled as {@linkplain ValueLayout value layouts} |
106 | | - * of a suitable carrier. The mapping between a scalar type and its corresponding layout is dependent on the ABI |
107 | | - * implemented by the native linker. For instance, the C type {@code long} maps to the layout constant |
108 | | - * {@link ValueLayout#JAVA_LONG} on Linux/x64, but maps to the layout constant {@link ValueLayout#JAVA_INT} on |
109 | | - * Windows/x64. Similarly, the C type {@code size_t} maps to the layout constant {@link ValueLayout#JAVA_LONG} |
110 | | - * on 64-bit platforms, but maps to the layout constant {@link ValueLayout#JAVA_INT} on 32-bit platforms. |
| 111 | + * of a suitable carrier. The {@linkplain #canonicalLayouts() mapping} between a scalar type and its corresponding |
| 112 | + * canonical layout is dependent on the ABI implemented by the native linker (see below). |
111 | 113 | * <p> |
112 | 114 | * Composite types are modelled as {@linkplain GroupLayout group layouts}. More specifically, a C {@code struct} type |
113 | 115 | * maps to a {@linkplain StructLayout struct layout}, whereas a C {@code union} type maps to a {@link UnionLayout union |
|
122 | 124 | * a pointer that is known to point to a C {@code int[2]} array can be modelled as an address layout whose |
123 | 125 | * target layout is a sequence layout whose element count is 2, and whose element type is {@link ValueLayout#JAVA_INT}. |
124 | 126 | * <p> |
125 | | - * The following table shows some examples of how C types are modelled in Linux/x64: |
| 127 | + * All native linker implementations are guaranteed to provide canonical layouts for the following set of types: |
| 128 | + * <ul> |
| 129 | + * <li>{@code bool}</li> |
| 130 | + * <li>{@code char}</li> |
| 131 | + * <li>{@code short}</li> |
| 132 | + * <li>{@code int}</li> |
| 133 | + * <li>{@code long}</li> |
| 134 | + * <li>{@code long long}</li> |
| 135 | + * <li>{@code float}</li> |
| 136 | + * <li>{@code double}</li> |
| 137 | + * <li>{@code size_t}</li> |
| 138 | + * <li>{@code wchar_t}</li> |
| 139 | + * <li>{@code void*}</li> |
| 140 | + * </ul> |
| 141 | + * As noted above, the specific canonical layout associated with each type can vary, depending on the data model |
| 142 | + * supported by a given ABI. For instance, the C type {@code long} maps to the layout constant {@link ValueLayout#JAVA_LONG} |
| 143 | + * on Linux/x64, but maps to the layout constant {@link ValueLayout#JAVA_INT} on Windows/x64. Similarly, the C type |
| 144 | + * {@code size_t} maps to the layout constant {@link ValueLayout#JAVA_LONG} on 64-bit platforms, but maps to the layout |
| 145 | + * constant {@link ValueLayout#JAVA_INT} on 32-bit platforms. |
| 146 | + * <p> |
| 147 | + * A native linker typically does not provide canonical layouts for C's unsigned integral types. Instead, they are |
| 148 | + * modelled using the canonical layouts associated with their corresponding signed integral types. For instance, |
| 149 | + * the C type {@code unsigned long} maps to the layout constant {@link ValueLayout#JAVA_LONG} on Linux/x64, but maps to |
| 150 | + * the layout constant {@link ValueLayout#JAVA_INT} on Windows/x64. |
| 151 | + * <p> |
| 152 | + * The following table shows some examples of how C types are modelled in Linux/x64 (all the examples provided |
| 153 | + * here will assume these platform-dependent mappings): |
126 | 154 | * |
127 | 155 | * <blockquote><table class="plain"> |
128 | 156 | * <caption style="display:none">Mapping C types</caption> |
|
137 | 165 | * <tr><th scope="row" style="font-weight:normal">{@code bool}</th> |
138 | 166 | * <td style="text-align:center;">{@link ValueLayout#JAVA_BOOLEAN}</td> |
139 | 167 | * <td style="text-align:center;">{@code boolean}</td> |
140 | | - * <tr><th scope="row" style="font-weight:normal">{@code char}</th> |
| 168 | + * <tr><th scope="row" style="font-weight:normal">{@code char} <br> {@code unsigned char}</th> |
141 | 169 | * <td style="text-align:center;">{@link ValueLayout#JAVA_BYTE}</td> |
142 | 170 | * <td style="text-align:center;">{@code byte}</td> |
143 | | - * <tr><th scope="row" style="font-weight:normal">{@code short}</th> |
| 171 | + * <tr><th scope="row" style="font-weight:normal">{@code short} <br> {@code unsigned short}</th> |
144 | 172 | * <td style="text-align:center;">{@link ValueLayout#JAVA_SHORT}</td> |
145 | 173 | * <td style="text-align:center;">{@code short}</td> |
146 | | - * <tr><th scope="row" style="font-weight:normal">{@code int}</th> |
| 174 | + * <tr><th scope="row" style="font-weight:normal">{@code int} <br> {@code unsigned int}</th> |
147 | 175 | * <td style="text-align:center;">{@link ValueLayout#JAVA_INT}</td> |
148 | 176 | * <td style="text-align:center;">{@code int}</td> |
149 | | - * <tr><th scope="row" style="font-weight:normal">{@code long}</th> |
| 177 | + * <tr><th scope="row" style="font-weight:normal">{@code long} <br> {@code unsigned long}</th> |
150 | 178 | * <td style="text-align:center;">{@link ValueLayout#JAVA_LONG}</td> |
151 | 179 | * <td style="text-align:center;">{@code long}</td> |
152 | | - * <tr><th scope="row" style="font-weight:normal">{@code long long}</th> |
| 180 | + * <tr><th scope="row" style="font-weight:normal">{@code long long} <br> {@code unsigned long long}</th> |
153 | 181 | * <td style="text-align:center;">{@link ValueLayout#JAVA_LONG}</td> |
154 | 182 | * <td style="text-align:center;">{@code long}</td> |
155 | 183 | * <tr><th scope="row" style="font-weight:normal">{@code float}</th> |
|
200 | 228 | * All native linker implementations operate on a subset of memory layouts. More formally, a layout {@code L} |
201 | 229 | * is supported by a native linker {@code NL} if: |
202 | 230 | * <ul> |
203 | | - * <li>{@code L} is a value layout {@code V} and {@code V.withoutName()} is {@linkplain MemoryLayout#equals(Object) equal} |
204 | | - * to one of the following layout constants: |
205 | | - * <ul> |
206 | | - * <li>{@link ValueLayout#JAVA_BOOLEAN}</li> |
207 | | - * <li>{@link ValueLayout#JAVA_BYTE}</li> |
208 | | - * <li>{@link ValueLayout#JAVA_CHAR}</li> |
209 | | - * <li>{@link ValueLayout#JAVA_SHORT}</li> |
210 | | - * <li>{@link ValueLayout#JAVA_INT}</li> |
211 | | - * <li>{@link ValueLayout#JAVA_LONG}</li> |
212 | | - * <li>{@link ValueLayout#JAVA_FLOAT}</li> |
213 | | - * <li>{@link ValueLayout#JAVA_DOUBLE}</li> |
214 | | - * </ul></li> |
215 | | - * <li>{@code L} is an address layout {@code A} and {@code A.withoutTargetLayout().withoutName()} is |
216 | | - * {@linkplain MemoryLayout#equals(Object) equal} to {@link ValueLayout#ADDRESS}</li> |
| 231 | + * <li>{@code L} is a value layout {@code V} and {@code V.withoutName()} is a canonical layout</li> |
217 | 232 | * <li>{@code L} is a sequence layout {@code S} and all the following conditions hold: |
218 | 233 | * <ol> |
219 | 234 | * <li>the alignment constraint of {@code S} is set to its <a href="MemoryLayout.html#layout-align">natural alignment</a>, and</li> |
@@ -492,6 +507,8 @@ public sealed interface Linker permits AbstractLinker { |
492 | 507 | * is the combination of OS and processor where the Java runtime is currently executing. |
493 | 508 | * |
494 | 509 | * @apiNote It is not currently possible to obtain a linker for a different combination of OS and processor. |
| 510 | + * @implSpec A native linker implementation is guaranteed to provide canonical layouts for |
| 511 | + * <a href="#describing-c-sigs">basic C types</a>. |
495 | 512 | * @implNote The libraries exposed by the {@linkplain #defaultLookup() default lookup} associated with the returned |
496 | 513 | * linker are the native libraries loaded in the process where the Java runtime is currently executing. For example, |
497 | 514 | * on Linux, these libraries typically include {@code libc}, {@code libm} and {@code libdl}. |
@@ -635,6 +652,22 @@ static Linker nativeLinker() { |
635 | 652 | */ |
636 | 653 | SymbolLookup defaultLookup(); |
637 | 654 |
|
| 655 | + /** |
| 656 | + * {@return an unmodifiable mapping between the names of data types used by the ABI implemented by this linker and their |
| 657 | + * <em>canonical layouts</em>} |
| 658 | + * <p> |
| 659 | + * Each {@link Linker} is responsible for choosing the data types that are widely recognized as useful on the OS |
| 660 | + * and processor combination supported by the {@link Linker}. Accordingly, the precise set of data type names |
| 661 | + * and canonical layouts exposed by the linker is unspecified; it varies from one {@link Linker} to another. |
| 662 | + * @implNote It is strongly recommended that the result of {@link #canonicalLayouts()} exposes a set of symbols that is stable over time. |
| 663 | + * Clients of {@link #canonicalLayouts()} are likely to fail if a data type that was previously exposed by the linker |
| 664 | + * is no longer exposed, or if its canonical layout is updated. |
| 665 | + * <p>If an implementer provides {@link Linker} implementations for multiple OS and processor combinations, then it is strongly |
| 666 | + * recommended that the result of {@link #canonicalLayouts()} exposes, as much as possible, a consistent set of symbols |
| 667 | + * across all the OS and processor combinations. |
| 668 | + */ |
| 669 | + Map<String, MemoryLayout> canonicalLayouts(); |
| 670 | + |
638 | 671 | /** |
639 | 672 | * A linker option is used to provide additional parameters to a linkage request. |
640 | 673 | * @since 20 |
|
0 commit comments