< prev index next >

src/java.base/share/classes/java/lang/foreign/Linker.java

Print this page
*** 27,18 ***
  
  import jdk.internal.foreign.abi.AbstractLinker;
  import jdk.internal.foreign.abi.LinkerOptions;
  import jdk.internal.foreign.abi.CapturableState;
  import jdk.internal.foreign.abi.SharedUtils;
- import jdk.internal.javac.PreviewFeature;
  import jdk.internal.reflect.CallerSensitive;
- import jdk.internal.reflect.Reflection;
  
  import java.lang.invoke.MethodHandle;
  import java.nio.ByteOrder;
  import java.util.Objects;
- import java.util.Optional;
  import java.util.Set;
  import java.util.function.Consumer;
  import java.util.stream.Collectors;
  import java.util.stream.Stream;
  
--- 27,16 ---
  
  import jdk.internal.foreign.abi.AbstractLinker;
  import jdk.internal.foreign.abi.LinkerOptions;
  import jdk.internal.foreign.abi.CapturableState;
  import jdk.internal.foreign.abi.SharedUtils;
  import jdk.internal.reflect.CallerSensitive;
  
  import java.lang.invoke.MethodHandle;
  import java.nio.ByteOrder;
+ import java.util.Map;
  import java.util.Objects;
  import java.util.Set;
  import java.util.function.Consumer;
  import java.util.stream.Collectors;
  import java.util.stream.Stream;
  

*** 57,10 ***
--- 55,16 ---
   * <li>A linker allows Java code to link against foreign functions, via
   * {@linkplain #downcallHandle(MemorySegment, FunctionDescriptor, Option...) downcall method handles}; and</li>
   * <li>A linker allows foreign functions to call Java method handles,
   * via the generation of {@linkplain #upcallStub(MethodHandle, FunctionDescriptor, Arena, Option...) upcall stubs}.</li>
   * </ul>
+  * A linker provides a way to look up the <em>canonical layouts</em> associated with the data types used by the ABI.
+  * For example, a linker implementing the C ABI might choose to provide a canonical layout for the C {@code size_t}
+  * type. On 64-bit platforms, this canonical layout might be equal to {@link ValueLayout#JAVA_LONG}. The canonical
+  * layouts supported by a linker are exposed via the {@link #canonicalLayouts()} method, which returns a map from
+  * type names to canonical layouts.
+  * <p>
   * In addition, a linker provides a way to look up foreign functions in libraries that conform to the ABI. Each linker
   * chooses a set of libraries that are commonly used on the OS and processor combination associated with the ABI.
   * For example, a linker for Linux/x64 might choose two libraries: {@code libc} and {@code libm}. The functions in these
   * libraries are exposed via a {@linkplain #defaultLookup() symbol lookup}.
   *

*** 90,26 ***
   * {@link #downcallHandle(MemorySegment, FunctionDescriptor, Option...)} method.
   * The obtained downcall method handle is then invoked as follows:
   *
   * {@snippet lang = java:
   * try (Arena arena = Arena.ofConfined()) {
!  *     MemorySegment str = arena.allocateUtf8String("Hello");
   *     long len = (long) strlen.invokeExact(str);  // 5
   * }
!  * }
   * <h3 id="describing-c-sigs">Describing C signatures</h3>
   *
   * When interacting with the native linker, clients must provide a platform-dependent description of the signature
   * of the C function they wish to link against. This description, a {@link FunctionDescriptor function descriptor},
   * defines the layouts associated with the parameter types and return type (if any) of the C function.
   * <p>
   * Scalar C types such as {@code bool}, {@code int} are modelled as {@linkplain ValueLayout value layouts}
!  * of a suitable carrier. The mapping between a scalar type and its corresponding layout is dependent on the ABI
!  * implemented by the native linker. For instance, the C type {@code long} maps to the layout constant
-  * {@link ValueLayout#JAVA_LONG} on Linux/x64, but maps to the layout constant {@link ValueLayout#JAVA_INT} on
-  * Windows/x64. Similarly, the C type {@code size_t} maps to the layout constant {@link ValueLayout#JAVA_LONG}
-  * on 64-bit platforms, but maps to the layout constant {@link ValueLayout#JAVA_INT} on 32-bit platforms.
   * <p>
   * Composite types are modelled as {@linkplain GroupLayout group layouts}. More specifically, a C {@code struct} type
   * maps to a {@linkplain StructLayout struct layout}, whereas a C {@code union} type maps to a {@link UnionLayout union
   * layout}. When defining a struct or union layout, clients must pay attention to the size and alignment constraint
   * of the corresponding composite type definition in C. For instance, padding between two struct fields
--- 94,23 ---
   * {@link #downcallHandle(MemorySegment, FunctionDescriptor, Option...)} method.
   * The obtained downcall method handle is then invoked as follows:
   *
   * {@snippet lang = java:
   * try (Arena arena = Arena.ofConfined()) {
!  *     MemorySegment str = arena.allocateFrom("Hello");
   *     long len = (long) strlen.invokeExact(str);  // 5
   * }
!  *}
   * <h3 id="describing-c-sigs">Describing C signatures</h3>
   *
   * When interacting with the native linker, clients must provide a platform-dependent description of the signature
   * of the C function they wish to link against. This description, a {@link FunctionDescriptor function descriptor},
   * defines the layouts associated with the parameter types and return type (if any) of the C function.
   * <p>
   * Scalar C types such as {@code bool}, {@code int} are modelled as {@linkplain ValueLayout value layouts}
!  * of a suitable carrier. The {@linkplain #canonicalLayouts() mapping} between a scalar type and its corresponding
!  * canonical layout is dependent on the ABI implemented by the native linker (see below).
   * <p>
   * Composite types are modelled as {@linkplain GroupLayout group layouts}. More specifically, a C {@code struct} type
   * maps to a {@linkplain StructLayout struct layout}, whereas a C {@code union} type maps to a {@link UnionLayout union
   * layout}. When defining a struct or union layout, clients must pay attention to the size and alignment constraint
   * of the corresponding composite type definition in C. For instance, padding between two struct fields

*** 120,11 ***
   * {@linkplain AddressLayout address layouts}. When the spatial bounds of the pointer type are known statically,
   * the address layout can be associated with a {@linkplain AddressLayout#targetLayout() target layout}. For instance,
   * a pointer that is known to point to a C {@code int[2]} array can be modelled as an address layout whose
   * target layout is a sequence layout whose element count is 2, and whose element type is {@link ValueLayout#JAVA_INT}.
   * <p>
!  * The following table shows some examples of how C types are modelled in Linux/x64:
   *
   * <blockquote><table class="plain">
   * <caption style="display:none">Mapping C types</caption>
   * <thead>
   * <tr>
--- 121,37 ---
   * {@linkplain AddressLayout address layouts}. When the spatial bounds of the pointer type are known statically,
   * the address layout can be associated with a {@linkplain AddressLayout#targetLayout() target layout}. For instance,
   * a pointer that is known to point to a C {@code int[2]} array can be modelled as an address layout whose
   * target layout is a sequence layout whose element count is 2, and whose element type is {@link ValueLayout#JAVA_INT}.
   * <p>
!  * All native linker implementations are guaranteed to provide canonical layouts for the following set of types:
+  * <ul>
+  *     <li>{@code bool}</li>
+  *     <li>{@code char}</li>
+  *     <li>{@code short}</li>
+  *     <li>{@code int}</li>
+  *     <li>{@code long}</li>
+  *     <li>{@code long long}</li>
+  *     <li>{@code float}</li>
+  *     <li>{@code double}</li>
+  *     <li>{@code size_t}</li>
+  *     <li>{@code wchar_t}</li>
+  *     <li>{@code void*}</li>
+  * </ul>
+  * As noted above, the specific canonical layout associated with each type can vary, depending on the data model
+  * supported by a given ABI. For instance, the C type {@code long} maps to the layout constant {@link ValueLayout#JAVA_LONG}
+  * on Linux/x64, but maps to the layout constant {@link ValueLayout#JAVA_INT} on Windows/x64. Similarly, the C type
+  * {@code size_t} maps to the layout constant {@link ValueLayout#JAVA_LONG} on 64-bit platforms, but maps to the layout
+  * constant {@link ValueLayout#JAVA_INT} on 32-bit platforms.
+  * <p>
+  * A native linker typically does not provide canonical layouts for C's unsigned integral types. Instead, they are
+  * modelled using the canonical layouts associated with their corresponding signed integral types. For instance,
+  * the C type {@code unsigned long} maps to the layout constant {@link ValueLayout#JAVA_LONG} on Linux/x64, but maps to
+  * the layout constant {@link ValueLayout#JAVA_INT} on Windows/x64.
+  * <p>
+  * The following table shows some examples of how C types are modelled in Linux/x64 (all the examples provided
+  * here will assume these platform-dependent mappings):
   *
   * <blockquote><table class="plain">
   * <caption style="display:none">Mapping C types</caption>
   * <thead>
   * <tr>

*** 135,23 ***
   * </thead>
   * <tbody>
   * <tr><th scope="row" style="font-weight:normal">{@code bool}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_BOOLEAN}</td>
   *     <td style="text-align:center;">{@code boolean}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code char}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_BYTE}</td>
   *     <td style="text-align:center;">{@code byte}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code short}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_SHORT}</td>
   *     <td style="text-align:center;">{@code short}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code int}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_INT}</td>
   *     <td style="text-align:center;">{@code int}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code long}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_LONG}</td>
   *     <td style="text-align:center;">{@code long}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code long long}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_LONG}</td>
   *     <td style="text-align:center;">{@code long}</td>
   * <tr><th scope="row" style="font-weight:normal">{@code float}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_FLOAT}</td>
   *     <td style="text-align:center;">{@code float}</td>
--- 162,23 ---
   * </thead>
   * <tbody>
   * <tr><th scope="row" style="font-weight:normal">{@code bool}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_BOOLEAN}</td>
   *     <td style="text-align:center;">{@code boolean}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code char} <br> {@code unsigned char}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_BYTE}</td>
   *     <td style="text-align:center;">{@code byte}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code short} <br> {@code unsigned short}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_SHORT}</td>
   *     <td style="text-align:center;">{@code short}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code int} <br> {@code unsigned int}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_INT}</td>
   *     <td style="text-align:center;">{@code int}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code long} <br> {@code unsigned long}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_LONG}</td>
   *     <td style="text-align:center;">{@code long}</td>
!  * <tr><th scope="row" style="font-weight:normal">{@code long long} <br> {@code unsigned long long}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_LONG}</td>
   *     <td style="text-align:center;">{@code long}</td>
   * <tr><th scope="row" style="font-weight:normal">{@code float}</th>
   *     <td style="text-align:center;">{@link ValueLayout#JAVA_FLOAT}</td>
   *     <td style="text-align:center;">{@code float}</td>

*** 198,24 ***
   * </table></blockquote>
   * <p>
   * All native linker implementations operate on a subset of memory layouts. More formally, a layout {@code L}
   * is supported by a native linker {@code NL} if:
   * <ul>
!  * <li>{@code L} is a value layout {@code V} and {@code V.withoutName()} is {@linkplain MemoryLayout#equals(Object) equal}
-  * to one of the following layout constants:
-  * <ul>
-  * <li>{@link ValueLayout#JAVA_BOOLEAN}</li>
-  * <li>{@link ValueLayout#JAVA_BYTE}</li>
-  * <li>{@link ValueLayout#JAVA_CHAR}</li>
-  * <li>{@link ValueLayout#JAVA_SHORT}</li>
-  * <li>{@link ValueLayout#JAVA_INT}</li>
-  * <li>{@link ValueLayout#JAVA_LONG}</li>
-  * <li>{@link ValueLayout#JAVA_FLOAT}</li>
-  * <li>{@link ValueLayout#JAVA_DOUBLE}</li>
-  * </ul></li>
-  * <li>{@code L} is an address layout {@code A} and {@code A.withoutTargetLayout().withoutName()} is
-  * {@linkplain MemoryLayout#equals(Object) equal} to {@link ValueLayout#ADDRESS}</li>
   * <li>{@code L} is a sequence layout {@code S} and all the following conditions hold:
   * <ol>
   * <li>the alignment constraint of {@code S} is set to its <a href="MemoryLayout.html#layout-align">natural alignment</a>, and</li>
   * <li>{@code S.elementLayout()} is a layout supported by {@code NL}.</li>
   * </ol>
--- 225,11 ---
   * </table></blockquote>
   * <p>
   * All native linker implementations operate on a subset of memory layouts. More formally, a layout {@code L}
   * is supported by a native linker {@code NL} if:
   * <ul>
!  * <li>{@code L} is a value layout {@code V} and {@code V.withoutName()} is a canonical layout</li>
   * <li>{@code L} is a sequence layout {@code S} and all the following conditions hold:
   * <ol>
   * <li>the alignment constraint of {@code S} is set to its <a href="MemoryLayout.html#layout-align">natural alignment</a>, and</li>
   * <li>{@code S.elementLayout()} is a layout supported by {@code NL}.</li>
   * </ol>

*** 291,11 ***
   * pointer, to the {@code qsort} downcall handle, as follows:
   *
   * {@snippet lang = java:
   * try (Arena arena = Arena.ofConfined()) {
   *     MemorySegment comparFunc = linker.upcallStub(comparHandle, comparDesc, arena);
!  *     MemorySegment array = arena.allocateArray(JAVA_INT, 0, 9, 3, 4, 6, 5, 1, 8, 2, 7);
   *     qsort.invokeExact(array, 10L, 4L, comparFunc);
   *     int[] sorted = array.toArray(JAVA_INT); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
   * }
   * }
   *
--- 305,11 ---
   * pointer, to the {@code qsort} downcall handle, as follows:
   *
   * {@snippet lang = java:
   * try (Arena arena = Arena.ofConfined()) {
   *     MemorySegment comparFunc = linker.upcallStub(comparHandle, comparDesc, arena);
!  *     MemorySegment array = arena.allocateFrom(JAVA_INT, 0, 9, 3, 4, 6, 5, 1, 8, 2, 7);
   *     qsort.invokeExact(array, 10L, 4L, comparFunc);
   *     int[] sorted = array.toArray(JAVA_INT); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
   * }
   * }
   *

*** 388,19 ***
   * specifically, the obtained segment has the desired size, can only be accessed by a single thread (the thread which created
   * the confined arena), and its lifetime is tied to the surrounding <em>try-with-resources</em> block.
   *
   * <h3 id="variadic-funcs">Variadic functions</h3>
   *
!  * Variadic functions are C functions which can accept a variable number and type of arguments. They are declared:
!  * <ol>
!  * <li>With a trailing ellipsis ({@code ...}) at the end of the formal parameter list, such as: {@code void foo(int x, ...);}</li>
!  * <li>With an empty formal parameter list, called a prototype-less function, such as: {@code void foo();}</li>
!  * </ol>
-  * The arguments passed in place of the ellipsis, or the arguments passed to a prototype-less function are called
-  * <em>variadic arguments</em>. Variadic functions are, essentially, templates that can be <em>specialized</em> into multiple
-  * non-variadic functions by replacing the {@code ...} or empty formal parameter list with a list of <em>variadic parameters</em>
-  * of a fixed number and type.
   * <p>
   * It should be noted that values passed as variadic arguments undergo default argument promotion in C. For instance, the
   * following argument promotions are applied:
   * <ul>
   * <li>{@code _Bool} -> {@code unsigned int}</li>
--- 402,15 ---
   * specifically, the obtained segment has the desired size, can only be accessed by a single thread (the thread which created
   * the confined arena), and its lifetime is tied to the surrounding <em>try-with-resources</em> block.
   *
   * <h3 id="variadic-funcs">Variadic functions</h3>
   *
!  * Variadic functions are C functions which can accept a variable number and type of arguments. They are declared with a
!  * trailing ellipsis ({@code ...}) at the end of the formal parameter list, such as: {@code void foo(int x, ...);}.
!  * The arguments passed in place of the ellipsis are called <em>variadic arguments</em>. Variadic functions are,
!  * essentially, templates that can be <em>specialized</em> into multiple non-variadic functions by replacing the
!  * {@code ...} with a list of <em>variadic parameters</em> of a fixed number and type.
   * <p>
   * It should be noted that values passed as variadic arguments undergo default argument promotion in C. For instance, the
   * following argument promotions are applied:
   * <ul>
   * <li>{@code _Bool} -> {@code unsigned int}</li>

*** 408,25 ***
   * <li>{@code [signed] short} -> {@code [signed] int}</li>
   * <li>{@code float} -> {@code double}</li>
   * </ul>
   * whereby the signed-ness of the source type corresponds to the signed-ness of the promoted type. The complete process
   * of default argument promotion is described in the C specification. In effect these promotions place limits on the
!  * specialized form of a variadic function, as the variadic parameters of the specialized form will always have a promoted
!  * type.
   * <p>
   * The native linker only supports linking the specialized form of a variadic function. A variadic function in its specialized
   * form can be linked using a function descriptor describing the specialized form. Additionally, the
   * {@link Linker.Option#firstVariadicArg(int)} linker option must be provided to indicate the first variadic parameter in
   * the parameter list. The corresponding argument layout (if any), and all following argument layouts in the specialized
!  * function descriptor, are called <em>variadic argument layouts</em>. For a prototype-less function, the index passed to
-  * {@link Linker.Option#firstVariadicArg(int)} should always be {@code 0}.
   * <p>
!  * The native linker will reject an attempt to link a specialized function descriptor with any variadic argument layouts
!  * corresponding to a C type that would be subject to default argument promotion (as described above). Exactly which layouts
!  * will be rejected is platform specific, but as an example: on Linux/x64 the layouts {@link ValueLayout#JAVA_BOOLEAN},
!  * {@link ValueLayout#JAVA_BYTE}, {@link ValueLayout#JAVA_CHAR}, {@link ValueLayout#JAVA_SHORT}, and
!  * {@link ValueLayout#JAVA_FLOAT} will be rejected.
   * <p>
   * A well-known variadic function is the {@code printf} function, defined in the C standard library:
   *
   * {@snippet lang = c:
   * int printf(const char *format, ...);
--- 418,26 ---
   * <li>{@code [signed] short} -> {@code [signed] int}</li>
   * <li>{@code float} -> {@code double}</li>
   * </ul>
   * whereby the signed-ness of the source type corresponds to the signed-ness of the promoted type. The complete process
   * of default argument promotion is described in the C specification. In effect these promotions place limits on the
!  * types that can be used to replace the {@code ...}, as the variadic parameters of the specialized form of a variadic
!  * function will always have a promoted type.
   * <p>
   * The native linker only supports linking the specialized form of a variadic function. A variadic function in its specialized
   * form can be linked using a function descriptor describing the specialized form. Additionally, the
   * {@link Linker.Option#firstVariadicArg(int)} linker option must be provided to indicate the first variadic parameter in
   * the parameter list. The corresponding argument layout (if any), and all following argument layouts in the specialized
!  * function descriptor, are called <em>variadic argument layouts</em>.
   * <p>
!  * The native linker does not automatically perform default argument promotions. However, since passing an argument of a
!  * non-promoted type as a variadic argument is not supported in C, the native linker will reject an attempt to link a
!  * specialized function descriptor with any variadic argument value layouts corresponding to a non-promoted C type.
!  * Since the size of the C {@code int} type is platform-specific, exactly which layouts will be rejected is
!  * platform-specific as well. As an example: on Linux/x64 the layouts corresponding to the C types {@code _Bool},
+  * {@code (unsigned) char}, {@code (unsigned) short}, and {@code float} (among others), will be rejected by the linker.
+  * The {@link #canonicalLayouts()} method can be used to find which layout corresponds to a particular C type.
   * <p>
   * A well-known variadic function is the {@code printf} function, defined in the C standard library:
   *
   * {@snippet lang = c:
   * int printf(const char *format, ...);

*** 458,13 ***
   *
   * We can then call the specialized downcall handle as usual:
   *
   * {@snippet lang = java:
   * try (Arena arena = Arena.ofConfined()) {
!  *     int res = (int)printf.invokeExact(arena.allocateUtf8String("%d plus %d equals %d"), 2, 2, 4); //prints "2 plus 2 equals 4"
-  * }
   * }
   *
   * <h2 id="safety">Safety considerations</h2>
   *
   * Creating a downcall method handle is intrinsically unsafe. A symbol in a foreign library does not, in general,
   * contain enough signature information (e.g. arity and types of foreign function parameters). As a consequence,
--- 469,13 ---
   *
   * We can then call the specialized downcall handle as usual:
   *
   * {@snippet lang = java:
   * try (Arena arena = Arena.ofConfined()) {
!  *     int res = (int)printf.invokeExact(arena.allocateFrom("%d plus %d equals %d"), 2, 2, 4); //prints "2 plus 2 equals 4"
   * }
+  *}
   *
   * <h2 id="safety">Safety considerations</h2>
   *
   * Creating a downcall method handle is intrinsically unsafe. A symbol in a foreign library does not, in general,
   * contain enough signature information (e.g. arity and types of foreign function parameters). As a consequence,

*** 480,25 ***
   * and even JVM crashes, since an upcall is typically executed in the context of a downcall method handle invocation.
   *
   * @implSpec
   * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
   *
!  * @since 19
   */
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
  public sealed interface Linker permits AbstractLinker {
  
      /**
       * {@return a linker for the ABI associated with the underlying native platform} The underlying native platform
       * is the combination of OS and processor where the Java runtime is currently executing.
       *
       * @apiNote It is not currently possible to obtain a linker for a different combination of OS and processor.
       * @implNote The libraries exposed by the {@linkplain #defaultLookup() default lookup} associated with the returned
       * linker are the native libraries loaded in the process where the Java runtime is currently executing. For example,
       * on Linux, these libraries typically include {@code libc}, {@code libm} and {@code libdl}.
-      *
-      * @throws UnsupportedOperationException if the underlying native platform is not supported.
       */
      static Linker nativeLinker() {
          return SharedUtils.getSystemLinker();
      }
  
--- 491,24 ---
   * and even JVM crashes, since an upcall is typically executed in the context of a downcall method handle invocation.
   *
   * @implSpec
   * Implementations of this interface are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
   *
!  * @since 22
   */
  public sealed interface Linker permits AbstractLinker {
  
      /**
       * {@return a linker for the ABI associated with the underlying native platform} The underlying native platform
       * is the combination of OS and processor where the Java runtime is currently executing.
       *
       * @apiNote It is not currently possible to obtain a linker for a different combination of OS and processor.
+      * @implSpec A native linker implementation is guaranteed to provide canonical layouts for
+      * <a href="#describing-c-sigs">basic C types</a>.
       * @implNote The libraries exposed by the {@linkplain #defaultLookup() default lookup} associated with the returned
       * linker are the native libraries loaded in the process where the Java runtime is currently executing. For example,
       * on Linux, these libraries typically include {@code libc}, {@code libm} and {@code libdl}.
       */
      static Linker nativeLinker() {
          return SharedUtils.getSystemLinker();
      }
  

*** 556,12 ***
       * a fresh scope that is always alive. Under normal conditions, the size of the returned segment is {@code 0}.
       * However, if the function descriptor's return layout has a {@linkplain AddressLayout#targetLayout() target layout}
       * {@code T}, then the size of the returned segment is set to {@code T.byteSize()}.
       * <p>
       * The returned method handle will throw an {@link IllegalArgumentException} if the {@link MemorySegment}
!      * representing the target address of the foreign function is the {@link MemorySegment#NULL} address.
!      * The returned method handle will additionally throw {@link NullPointerException} if any argument passed to it is {@code null}.
       * <p>
       * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
       * Restricted methods are unsafe, and, if used incorrectly, their use might crash
       * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
       * restricted methods, and use safe and supported functionalities, where possible.
--- 566,16 ---
       * a fresh scope that is always alive. Under normal conditions, the size of the returned segment is {@code 0}.
       * However, if the function descriptor's return layout has a {@linkplain AddressLayout#targetLayout() target layout}
       * {@code T}, then the size of the returned segment is set to {@code T.byteSize()}.
       * <p>
       * The returned method handle will throw an {@link IllegalArgumentException} if the {@link MemorySegment}
!      * representing the target address of the foreign function is the {@link MemorySegment#NULL} address. If an argument
!      * is a {@link MemorySegment},whose corresponding layout is an {@linkplain GroupLayout group layout}, the linker might attempt to access the contents of the segment. As such, one of the exceptions specified by the
+      * {@link MemorySegment#get(ValueLayout.OfByte, long)} or the
+      * {@link MemorySegment#copy(MemorySegment, long, MemorySegment, long, long)} methods may be thrown.
+      * The returned method handle will additionally throw {@link NullPointerException} if any argument
+      * passed to it is {@code null}.
       * <p>
       * This method is <a href="package-summary.html#restricted"><em>restricted</em></a>.
       * Restricted methods are unsafe, and, if used incorrectly, their use might crash
       * the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on
       * restricted methods, and use safe and supported functionalities, where possible.

*** 633,15 ***
       * across all the OS and processor combinations.
       * @return a symbol lookup for symbols in a set of commonly used libraries.
       */
      SymbolLookup defaultLookup();
  
      /**
       * A linker option is used to provide additional parameters to a linkage request.
!      * @since 20
       */
-     @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
      sealed interface Option
              permits LinkerOptions.LinkerOptionImpl {
  
          /**
           * {@return a linker option used to denote the index indicating the start of the variadic arguments passed to the
--- 647,30 ---
       * across all the OS and processor combinations.
       * @return a symbol lookup for symbols in a set of commonly used libraries.
       */
      SymbolLookup defaultLookup();
  
+     /**
+      * {@return an unmodifiable mapping between the names of data types used by the ABI implemented by this linker and their
+      * <em>canonical layouts</em>}
+      * <p>
+      * Each {@link Linker} is responsible for choosing the data types that are widely recognized as useful on the OS
+      * and processor combination supported by the {@link Linker}. Accordingly, the precise set of data type names
+      * and canonical layouts exposed by the linker is unspecified; it varies from one {@link Linker} to another.
+      * @implNote It is strongly recommended that the result of {@link #canonicalLayouts()} exposes a set of symbols that is stable over time.
+      * Clients of {@link #canonicalLayouts()} are likely to fail if a data type that was previously exposed by the linker
+      * is no longer exposed, or if its canonical layout is updated.
+      * <p>If an implementer provides {@link Linker} implementations for multiple OS and processor combinations, then it is strongly
+      * recommended that the result of {@link #canonicalLayouts()} exposes, as much as possible, a consistent set of symbols
+      * across all the OS and processor combinations.
+      */
+     Map<String, MemoryLayout> canonicalLayouts();
+ 
      /**
       * A linker option is used to provide additional parameters to a linkage request.
!      * @since 22
       */
      sealed interface Option
              permits LinkerOptions.LinkerOptionImpl {
  
          /**
           * {@return a linker option used to denote the index indicating the start of the variadic arguments passed to the

*** 702,10 ***
--- 731,12 ---
           *     int errno = (int) errnoHandle.get(capturedState);
           *     // use errno
           * }
           * }
           *
+          * @apiNote This linker option can not be combined with {@link #critical}.
+          *
           * @param capturedState the names of the values to save.
           * @throws IllegalArgumentException if at least one of the provided {@code capturedState} names
           *                                  is unsupported on the current platform.
           * @see #captureStateLayout()
           */

*** 744,21 ***
          static StructLayout captureStateLayout() {
              return CapturableState.LAYOUT;
          }
  
          /**
!          * {@return a linker option used to mark a foreign function as <em>trivial</em>}
           * <p>
!          * A trivial function is a function that has an extremely short running time
!          * in all cases (similar to calling an empty function), and does not call back into Java (e.g. using an upcall stub).
           * <p>
           * Using this linker option is a hint which some implementations may use to apply
!          * optimizations that are only valid for trivial functions.
           * <p>
!          * Using this linker option when linking non trivial functions is likely to have adverse effects,
           * such as loss of performance, or JVM crashes.
           */
!         static Option isTrivial() {
!             return LinkerOptions.IsTrivial.INSTANCE;
          }
      }
  }
--- 775,21 ---
          static StructLayout captureStateLayout() {
              return CapturableState.LAYOUT;
          }
  
          /**
!          * {@return a linker option used to mark a foreign function as <em>critical</em>}
           * <p>
!          * A critical function is a function that has an extremely short running time in all cases
!          * (similar to calling an empty function), and does not call back into Java (e.g. using an upcall stub).
           * <p>
           * Using this linker option is a hint which some implementations may use to apply
!          * optimizations that are only valid for critical functions.
           * <p>
!          * Using this linker option when linking non-critical functions is likely to have adverse effects,
           * such as loss of performance, or JVM crashes.
           */
!         static Option critical() {
!             return LinkerOptions.Critical.INSTANCE;
          }
      }
  }
< prev index next >