Module jdk.incubator.foreign
Package jdk.incubator.foreign

# Interface CLinker.VaList

All Superinterfaces:
  `Addressable`

Enclosing interface:
  CLinker

public static sealed interface CLinker.VaList extends Addressable
An interface that models a C `va_list`.

A va list is a stateful cursor used to iterate over a set of variadic arguments.

Per the C specification (see C standard 6.5.2.2 Function calls - item 6), arguments to variadic calls are erased by way of 'default argument promotions', which erases integral types by way of integer promotion (see C standard 6.3.1.1 - item 2), and which erases all `float` arguments to `double`.

As such, this interface only supports reading `int`, `double`, and any other type that fits into a `long`.

Unless otherwise specified, passing a `null` argument, or an array argument containing one or more `null` elements to a method in this class causes a `NullPointerException` to be thrown.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Interface
  Description
  `static interface`
  `CLinker.VaList.Builder`
  A builder interface used to construct a C `va_list`.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `MemoryAddress`
  `address()`
  Returns the memory address of the C `va_list` associated with this instance.
  `CLinker.VaList`
  `copy()`
  Copies this C `va_list` at its current position.
  `static CLinker.VaList`
  `empty()`
  Returns an empty C `va_list` constant.
  `static CLinker.VaList`
  `make(Consumer<CLinker.VaList.Builder> actions, ResourceScope scope)`
  Constructs a new `VaList` using a builder (see `CLinker.VaList.Builder`), associated with a given resource scope.
  `static CLinker.VaList`
  `ofAddress(MemoryAddress address)`
  Constructs a new `VaList` instance out of a memory address pointing to an existing C `va_list`, backed by the global resource scope.
  `static CLinker.VaList`
  `ofAddress(MemoryAddress address, ResourceScope scope)`
  Constructs a new `VaList` instance out of a memory address pointing to an existing C `va_list`, with given resource scope.
  `ResourceScope`
  `scope()`
  Returns the resource scope associated with this instance.
  `void`
  `skip(MemoryLayout... layouts)`
  Skips a number of elements with the given memory layouts, and advances this va list's position.
  `MemoryAddress`
  `vargAsAddress(MemoryLayout layout)`
  Reads the next value as a `MemoryAddress` and advances this va list's position.
  `double`
  `vargAsDouble(MemoryLayout layout)`
  Reads the next value as a `double` and advances this va list's position.
  `int`
  `vargAsInt(MemoryLayout layout)`
  Reads the next value as an `int` and advances this va list's position.
  `long`
  `vargAsLong(MemoryLayout layout)`
  Reads the next value as a `long` and advances this va list's position.
  `MemorySegment`
  `vargAsSegment(MemoryLayout layout, ResourceScope scope)`
  Reads the next value as a `MemorySegment`, and advances this va list's position.
  `MemorySegment`
  `vargAsSegment(MemoryLayout layout, SegmentAllocator allocator)`
  Reads the next value as a `MemorySegment`, and advances this va list's position.

- ## Method Details

  - ### vargAsInt

    int vargAsInt(MemoryLayout layout)
    Reads the next value as an `int` and advances this va list's position.
    Parameters:
      `layout` - the layout of the value
    Returns:
      the value read as an `int`
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).
      `IllegalArgumentException` - if the given memory layout is not compatible with `int`

  - ### vargAsLong

    long vargAsLong(MemoryLayout layout)
    Reads the next value as a `long` and advances this va list's position.
    Parameters:
      `layout` - the layout of the value
    Returns:
      the value read as an `long`
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).
      `IllegalArgumentException` - if the given memory layout is not compatible with `long`

  - ### vargAsDouble

    double vargAsDouble(MemoryLayout layout)
    Reads the next value as a `double` and advances this va list's position.
    Parameters:
      `layout` - the layout of the value
    Returns:
      the value read as an `double`
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).
      `IllegalArgumentException` - if the given memory layout is not compatible with `double`

  - ### vargAsAddress

    MemoryAddress vargAsAddress(MemoryLayout layout)
    Reads the next value as a `MemoryAddress` and advances this va list's position.
    Parameters:
      `layout` - the layout of the value
    Returns:
      the value read as an `MemoryAddress`
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).
      `IllegalArgumentException` - if the given memory layout is not compatible with `MemoryAddress`

  - ### vargAsSegment

    MemorySegment vargAsSegment(MemoryLayout layout, SegmentAllocator allocator)
    Reads the next value as a `MemorySegment`, and advances this va list's position.

    The memory segment returned by this method will be allocated using the given `SegmentAllocator`.

    Parameters:
      `layout` - the layout of the value
      `allocator` - the allocator to be used for the native segment allocation
    Returns:
      the value read as an `MemorySegment`
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).
      `IllegalArgumentException` - if the given memory layout is not compatible with `MemorySegment`

  - ### vargAsSegment

    MemorySegment vargAsSegment(MemoryLayout layout, ResourceScope scope)
    Reads the next value as a `MemorySegment`, and advances this va list's position.

    The memory segment returned by this method will be associated with the given `ResourceScope`.

    Parameters:
      `layout` - the layout of the value
      `scope` - the resource scope to be associated with the returned segment
    Returns:
      the value read as an `MemorySegment`
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).
      `IllegalArgumentException` - if the given memory layout is not compatible with `MemorySegment`
      `IllegalStateException` - if `scope` has been already closed, or if access occurs from a thread other than the thread owning `scope`.

  - ### skip

    void skip(MemoryLayout... layouts)
    Skips a number of elements with the given memory layouts, and advances this va list's position.
    Parameters:
      `layouts` - the layout of the value
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).

  - ### scope

    ResourceScope scope()
    Returns the resource scope associated with this instance.
    Returns:
      the resource scope associated with this instance.

  - ### copy

    CLinker.VaList copy()
    Copies this C `va_list` at its current position. Copying is useful to traverse the va list's elements starting from the current position, without affecting the state of the original va list, essentially allowing the elements to be traversed multiple times.

    Any native resource required by the execution of this method will be allocated in the resource scope associated with this instance (see `scope()`).

    This method only copies the va list cursor itself and not the memory that may be attached to the va list which holds its elements. That means that if this va list was created with the `make(Consumer, ResourceScope)` method, closing this va list will also release the native memory that holds its elements, making the copy unusable.

    Returns:
      a copy of this C `va_list`.
    Throws:
      `IllegalStateException` - if the resource scope associated with this instance has been closed (see `scope()`).

  - ### address

    MemoryAddress address()
    Returns the memory address of the C `va_list` associated with this instance. The returned memory address is associated with same resource scope as that associated with this instance.
    Specified by:
      `address` in interface `Addressable`
    Returns:
      the memory address of the C `va_list` associated with this instance.

  - ### ofAddress

    static CLinker.VaList ofAddress(MemoryAddress address)
    Constructs a new `VaList` instance out of a memory address pointing to an existing C `va_list`, backed by the global resource scope.

    This method is restricted. 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.

    Parameters:
      `address` - a memory address pointing to an existing C `va_list`.
    Returns:
      a new `VaList` instance backed by the C `va_list` at `address`.
    Throws:
      `IllegalCallerException` - if access to this method occurs from a module `M` and the command line option `--enable-native-access` is either absent, or does not mention the module name `M`, or `ALL-UNNAMED` in case `M` is an unnamed module.

  - ### ofAddress

    static CLinker.VaList ofAddress(MemoryAddress address, ResourceScope scope)
    Constructs a new `VaList` instance out of a memory address pointing to an existing C `va_list`, with given resource scope.

    This method is restricted. 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.

    Parameters:
      `address` - a memory address pointing to an existing C `va_list`.
      `scope` - the resource scope to be associated with the returned `VaList` instance.
    Returns:
      a new `VaList` instance backed by the C `va_list` at `address`.
    Throws:
      `IllegalStateException` - if `scope` has been already closed, or if access occurs from a thread other than the thread owning `scope`.
      `IllegalCallerException` - if access to this method occurs from a module `M` and the command line option `--enable-native-access` is either absent, or does not mention the module name `M`, or `ALL-UNNAMED` in case `M` is an unnamed module.

  - ### make

    static CLinker.VaList make(Consumer<CLinker.VaList.Builder> actions, ResourceScope scope)
    Constructs a new `VaList` using a builder (see `CLinker.VaList.Builder`), associated with a given resource scope.

    If this method needs to allocate native memory, such memory will be managed by the given resource scope, and will be released when the resource scope is closed.

    Note that when there are no elements added to the created va list, this method will return the same as `empty()`.

    Parameters:
      `actions` - a consumer for a builder (see `CLinker.VaList.Builder`) which can be used to specify the elements of the underlying C `va_list`.
      `scope` - the scope to be used for the valist allocation.
    Returns:
      a new `VaList` instance backed by a fresh C `va_list`.
    Throws:
      `IllegalStateException` - if `scope` has been already closed, or if access occurs from a thread other than the thread owning `scope`.

  - ### empty

    static CLinker.VaList empty()
    Returns an empty C `va_list` constant.

    The returned `VaList` can not be closed.

    Returns:
      a `VaList` modelling an empty C `va_list`.