8295044: Implementation of Foreign Function and Memory API (Second Preview)

Co-authored-by: Jorn Vernee <jvernee@openjdk.org>
Co-authored-by: Per Minborg <pminborg@openjdk.org>
Co-authored-by: Maurizio Cimadamore <mcimadamore@openjdk.org>
Reviewed-by: jvernee, pminborg, psandoz, alanb, sundar
This commit is contained in:
Maurizio Cimadamore 2022-12-05 13:49:53 +00:00
parent bd381886e0
commit 73baadceb6
252 changed files with 9221 additions and 7889 deletions

View file

@ -28,102 +28,49 @@ package java.lang.foreign;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import jdk.internal.foreign.Utils;
import jdk.internal.foreign.layout.ValueLayouts;
import jdk.internal.javac.PreviewFeature;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;
import sun.invoke.util.Wrapper;
import jdk.internal.reflect.CallerSensitive;
/**
* A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as <em>integral</em> types
* (either signed or unsigned) and <em>floating-point</em> types. Each value layout has a size, an alignment (in bits),
* A layout that models values of basic data types. Examples of values modelled by a value layout are
* <em>integral</em> values (either signed or unsigned), <em>floating-point</em> values and
* <em>address</em> values.
* <p>
* Each value layout has a size, an alignment (in bits),
* a {@linkplain ByteOrder byte order}, and a <em>carrier</em>, that is, the Java type that should be used when
* {@linkplain MemorySegment#get(OfInt, long) accessing} a memory region using the value layout.
* {@linkplain MemorySegment#get(OfInt, long) accessing} a region of memory using the value layout.
* <p>
* This class defines useful value layout constants for Java primitive types and addresses.
* The layout constants in this class make implicit alignment and byte-ordering assumption: all layout
* constants in this class are byte-aligned, and their byte order is set to the {@linkplain ByteOrder#nativeOrder() platform default},
* thus making it easy to work with other APIs, such as arrays and {@link java.nio.ByteBuffer}.
*
* @implSpec
* This class and its subclasses are immutable, thread-safe and <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>.
* @implSpec implementing classes and subclasses 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 class ValueLayout extends AbstractLayout implements MemoryLayout {
private final Class<?> carrier;
private final ByteOrder order;
private static final int ADDRESS_SIZE_BITS = Unsafe.ADDRESS_SIZE * 8;
ValueLayout(Class<?> carrier, ByteOrder order, long size) {
this(carrier, order, size, size, Optional.empty());
}
ValueLayout(Class<?> carrier, ByteOrder order, long size, long alignment, Optional<String> name) {
super(size, alignment, name);
this.carrier = carrier;
this.order = order;
checkCarrierSize(carrier, size);
}
public sealed interface ValueLayout extends MemoryLayout {
/**
* {@return the value's byte order}
*/
public ByteOrder order() {
return order;
}
ByteOrder order();
/**
* Returns a value layout with the same carrier, alignment constraints and name as this value layout,
* Returns a value layout with the same carrier, alignment constraint and name as this value layout,
* but with the specified byte order.
*
* @param order the desired byte order.
* @return a value layout with the given byte order.
*/
public ValueLayout withOrder(ByteOrder order) {
return new ValueLayout(carrier, Objects.requireNonNull(order), bitSize(), alignment, name());
}
ValueLayout withOrder(ByteOrder order);
/**
* {@inheritDoc}
*/
@Override
public String toString() {
char descriptor = carrier == MemoryAddress.class ? 'A' : carrier.descriptorString().charAt(0);
if (order == ByteOrder.LITTLE_ENDIAN) {
descriptor = Character.toLowerCase(descriptor);
}
return decorateLayoutString(String.format("%s%d", descriptor, bitSize()));
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!super.equals(other)) {
return false;
}
return other instanceof ValueLayout otherValue &&
carrier.equals(otherValue.carrier) &&
order.equals(otherValue.order);
}
/**
* Creates a <em>strided</em> access var handle that can be used to dereference a multi-dimensional array. The
* layout of this array is a sequence layout with {@code shape.length} nested sequence layouts. The element
* Creates a <em>strided</em> var handle that can be used to access a memory segment as multi-dimensional
* array. The layout of this array is a sequence layout with {@code shape.length} nested sequence layouts. The element
* layout of the sequence layout at depth {@code shape.length} is this value layout.
* As a result, if {@code shape.length == 0}, the array layout will feature only one dimension.
* <p>
@ -138,15 +85,15 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout {
*
* Can be used to access a multi-dimensional array whose layout is as follows:
*
* {@snippet lang=java :
* SequenceLayout arrayLayout = MemoryLayout.sequenceLayout(-1,
* {@snippet lang = java:
* SequenceLayout arrayLayout = MemoryLayout.sequenceLayout(
* MemoryLayout.sequenceLayout(10,
* MemoryLayout.sequenceLayout(20, ValueLayout.JAVA_INT)));
* }
*}
*
* The resulting var handle {@code arrayHandle} will feature 3 coordinates of type {@code long}; each coordinate
* is interpreted as an index into the corresponding sequence layout. If we refer to the var handle coordinates, from left
* to right, as {@code x}, {@code y} and {@code z} respectively, the final offset dereferenced by the var handle can be
* to right, as {@code x}, {@code y} and {@code z} respectively, the final offset accessed by the var handle can be
* computed with the following formula:
*
* <blockquote><pre>{@code
@ -170,7 +117,8 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout {
* as the value for {@code z} is outside its specified bounds.
*
* @param shape the size of each nested array dimension.
* @return a var handle which can be used to dereference a multi-dimensional array, featuring {@code shape.length + 1}
* @return a var handle which can be used to access a memory segment as a multi-dimensional array,
* featuring {@code shape.length + 1}
* {@code long} coordinates.
* @throws IllegalArgumentException if {@code shape[i] < 0}, for at least one index {@code i}.
* @throws UnsupportedOperationException if {@code bitAlignment() > bitSize()}.
@ -178,504 +126,385 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout {
* @see MemoryLayout#varHandle(PathElement...)
* @see SequenceLayout
*/
public VarHandle arrayElementVarHandle(int... shape) {
Objects.requireNonNull(shape);
MemoryLayout layout = this;
List<PathElement> path = new ArrayList<>();
for (int i = shape.length ; i > 0 ; i--) {
int size = shape[i - 1];
if (size < 0) throw new IllegalArgumentException("Invalid shape size: " + size);
layout = MemoryLayout.sequenceLayout(size, layout);
path.add(PathElement.sequenceElement());
}
layout = MemoryLayout.sequenceLayout(-1, layout);
path.add(PathElement.sequenceElement());
return layout.varHandle(path.toArray(new PathElement[0]));
}
VarHandle arrayElementVarHandle(int... shape);
/**
* {@return the carrier associated with this value layout}
*/
public Class<?> carrier() {
return carrier;
}
Class<?> carrier();
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), order, carrier);
}
@Override
ValueLayout dup(long alignment, Optional<String> name) {
return new ValueLayout(carrier, order, bitSize(), alignment, name());
}
//hack: the declarations below are to make javadoc happy; we could have used generics in AbstractLayout
//but that causes issues with javadoc, see JDK-8224052
ValueLayout withName(String name);
/**
* {@inheritDoc}
*/
@Override
public ValueLayout withName(String name) {
return (ValueLayout)super.withName(name);
}
/**
* {@inheritDoc}
*/
@Override
public ValueLayout withBitAlignment(long alignmentBits) {
return (ValueLayout)super.withBitAlignment(alignmentBits);
}
static void checkCarrierSize(Class<?> carrier, long size) {
if (!isValidCarrier(carrier)) {
throw new IllegalArgumentException("Invalid carrier: " + carrier.getName());
}
if (carrier == MemoryAddress.class && size != ADDRESS_SIZE_BITS) {
throw new IllegalArgumentException("Address size mismatch: " + ADDRESS_SIZE_BITS + " != " + size);
}
if (carrier.isPrimitive()) {
int expectedSize = carrier == boolean.class ? 8 : Wrapper.forPrimitiveType(carrier).bitWidth();
if (size != expectedSize) {
throw new IllegalArgumentException("Carrier size mismatch: " + carrier.getName() + " != " + size);
}
}
}
static boolean isValidCarrier(Class<?> carrier) {
return carrier == boolean.class
|| carrier == byte.class
|| carrier == short.class
|| carrier == char.class
|| carrier == int.class
|| carrier == long.class
|| carrier == float.class
|| carrier == double.class
|| carrier == MemoryAddress.class;
}
@Stable
private VarHandle handle;
@ForceInline
VarHandle accessHandle() {
if (handle == null) {
// this store to stable field is safe, because return value of 'makeMemoryAccessVarHandle' has stable identity
handle = Utils.makeSegmentViewVarHandle(this);
}
return handle;
}
ValueLayout withBitAlignment(long bitAlignment);
/**
* A value layout whose carrier is {@code boolean.class}.
*
* @see #JAVA_BOOLEAN
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfBoolean extends ValueLayout {
OfBoolean(ByteOrder order) {
super(boolean.class, order, 8);
}
OfBoolean(ByteOrder order, long alignment, Optional<String> name) {
super(boolean.class, order, 8, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfBoolean extends ValueLayout permits ValueLayouts.OfBooleanImpl {
/**
* {@inheritDoc}
*/
@Override
OfBoolean dup(long alignment, Optional<String> name) {
return new OfBoolean(order(), alignment, name);
}
OfBoolean withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfBoolean withName(String name) {
return (OfBoolean)super.withName(name);
}
OfBoolean withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfBoolean withBitAlignment(long alignmentBits) {
return (OfBoolean)super.withBitAlignment(alignmentBits);
}
OfBoolean withOrder(ByteOrder order);
@Override
public OfBoolean withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfBoolean(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code byte.class}.
*
* @see #JAVA_BYTE
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfByte extends ValueLayout {
OfByte(ByteOrder order) {
super(byte.class, order, 8);
}
OfByte(ByteOrder order, long alignment, Optional<String> name) {
super(byte.class, order, 8, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfByte extends ValueLayout permits ValueLayouts.OfByteImpl {
/**
* {@inheritDoc}
*/
@Override
OfByte dup(long alignment, Optional<String> name) {
return new OfByte(order(), alignment, name);
}
OfByte withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfByte withName(String name) {
return (OfByte)super.withName(name);
}
OfByte withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfByte withBitAlignment(long alignmentBits) {
return (OfByte)super.withBitAlignment(alignmentBits);
}
OfByte withOrder(ByteOrder order);
@Override
public OfByte withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfByte(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code char.class}.
*
* @see #JAVA_CHAR
* @see #JAVA_CHAR_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfChar extends ValueLayout {
OfChar(ByteOrder order) {
super(char.class, order, 16);
}
OfChar(ByteOrder order, long alignment, Optional<String> name) {
super(char.class, order, 16, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfChar extends ValueLayout permits ValueLayouts.OfCharImpl {
/**
* {@inheritDoc}
*/
@Override
OfChar dup(long alignment, Optional<String> name) {
return new OfChar(order(), alignment, name);
}
OfChar withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfChar withName(String name) {
return (OfChar)super.withName(name);
}
OfChar withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfChar withBitAlignment(long alignmentBits) {
return (OfChar)super.withBitAlignment(alignmentBits);
}
OfChar withOrder(ByteOrder order);
@Override
public OfChar withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfChar(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code short.class}.
*
* @see #JAVA_SHORT
* @see #JAVA_SHORT_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfShort extends ValueLayout {
OfShort(ByteOrder order) {
super(short.class, order, 16);
}
OfShort(ByteOrder order, long alignment, Optional<String> name) {
super(short.class, order, 16, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfShort extends ValueLayout permits ValueLayouts.OfShortImpl {
/**
* {@inheritDoc}
*/
@Override
OfShort dup(long alignment, Optional<String> name) {
return new OfShort(order(), alignment, name);
}
OfShort withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfShort withName(String name) {
return (OfShort)super.withName(name);
}
OfShort withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfShort withBitAlignment(long alignmentBits) {
return (OfShort)super.withBitAlignment(alignmentBits);
}
OfShort withOrder(ByteOrder order);
@Override
public OfShort withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfShort(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code int.class}.
*
* @see #JAVA_INT
* @see #JAVA_INT_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfInt extends ValueLayout {
OfInt(ByteOrder order) {
super(int.class, order, 32);
}
OfInt(ByteOrder order, long alignment, Optional<String> name) {
super(int.class, order, 32, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfInt extends ValueLayout permits ValueLayouts.OfIntImpl {
/**
* {@inheritDoc}
*/
@Override
OfInt dup(long alignment, Optional<String> name) {
return new OfInt(order(), alignment, name);
}
OfInt withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfInt withName(String name) {
return (OfInt)super.withName(name);
}
OfInt withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfInt withBitAlignment(long alignmentBits) {
return (OfInt)super.withBitAlignment(alignmentBits);
}
OfInt withOrder(ByteOrder order);
@Override
public OfInt withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfInt(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code float.class}.
*
* @see #JAVA_FLOAT
* @see #JAVA_FLOAT_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfFloat extends ValueLayout {
OfFloat(ByteOrder order) {
super(float.class, order, 32);
}
OfFloat(ByteOrder order, long alignment, Optional<String> name) {
super(float.class, order, 32, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfFloat extends ValueLayout permits ValueLayouts.OfFloatImpl {
/**
* {@inheritDoc}
*/
@Override
OfFloat dup(long alignment, Optional<String> name) {
return new OfFloat(order(), alignment, name);
}
OfFloat withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfFloat withName(String name) {
return (OfFloat)super.withName(name);
}
OfFloat withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfFloat withBitAlignment(long alignmentBits) {
return (OfFloat)super.withBitAlignment(alignmentBits);
}
OfFloat withOrder(ByteOrder order);
@Override
public OfFloat withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfFloat(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code long.class}.
*
* @see #JAVA_LONG
* @see #JAVA_LONG_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfLong extends ValueLayout {
OfLong(ByteOrder order) {
super(long.class, order, 64);
}
OfLong(ByteOrder order, long alignment, Optional<String> name) {
super(long.class, order, 64, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfLong extends ValueLayout permits ValueLayouts.OfLongImpl {
/**
* {@inheritDoc}
*/
@Override
OfLong dup(long alignment, Optional<String> name) {
return new OfLong(order(), alignment, name);
}
OfLong withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfLong withName(String name) {
return (OfLong)super.withName(name);
}
OfLong withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfLong withBitAlignment(long alignmentBits) {
return (OfLong)super.withBitAlignment(alignmentBits);
}
OfLong withOrder(ByteOrder order);
@Override
public OfLong withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfLong(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code double.class}.
*
* @see #JAVA_DOUBLE
* @see #JAVA_DOUBLE_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfDouble extends ValueLayout {
OfDouble(ByteOrder order) {
super(double.class, order, 64);
}
OfDouble(ByteOrder order, long alignment, Optional<String> name) {
super(double.class, order, 64, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfDouble extends ValueLayout permits ValueLayouts.OfDoubleImpl {
/**
* {@inheritDoc}
*/
@Override
OfDouble dup(long alignment, Optional<String> name) {
return new OfDouble(order(), alignment, name);
}
OfDouble withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfDouble withName(String name) {
return (OfDouble)super.withName(name);
}
OfDouble withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfDouble withBitAlignment(long alignmentBits) {
return (OfDouble)super.withBitAlignment(alignmentBits);
}
OfDouble withOrder(ByteOrder order);
@Override
public OfDouble withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfDouble(order, alignment, name());
}
}
/**
* A value layout whose carrier is {@code MemoryAddress.class}.
* A value layout whose carrier is {@code MemorySegment.class}.
*
* @see #ADDRESS
* @see #ADDRESS_UNALIGNED
* @since 19
*/
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static final class OfAddress extends ValueLayout {
OfAddress(ByteOrder order) {
super(MemoryAddress.class, order, ADDRESS_SIZE_BITS);
}
OfAddress(ByteOrder order, long size, long alignment, Optional<String> name) {
super(MemoryAddress.class, order, size, alignment, name);
}
@PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
sealed interface OfAddress extends ValueLayout permits ValueLayouts.OfAddressImpl {
/**
* {@inheritDoc}
*/
@Override
OfAddress dup(long alignment, Optional<String> name) {
return new OfAddress(order(), bitSize(), alignment, name);
}
OfAddress withName(String name);
/**
* {@inheritDoc}
*/
@Override
public OfAddress withName(String name) {
return (OfAddress)super.withName(name);
}
OfAddress withBitAlignment(long bitAlignment);
/**
* {@inheritDoc}
*/
@Override
public OfAddress withBitAlignment(long alignmentBits) {
return (OfAddress)super.withBitAlignment(alignmentBits);
}
OfAddress withOrder(ByteOrder order);
/**
* Returns an <em>unbounded</em> address layout with the same carrier, alignment constraint, name and order as this address layout,
* but with the specified pointee layout. An unbounded address layout allow raw addresses to be accessed
* as {@linkplain MemorySegment memory segments} whose size is set to {@link Long#MAX_VALUE}. As such,
* these segments can be used in subsequent access operations.
* <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.
*
* @return an unbounded address layout with same characteristics as this layout.
* @see #isUnbounded()
*/
@CallerSensitive
OfAddress asUnbounded();
/**
* {@return {@code true}, if this address layout is an {@linkplain #asUnbounded() unbounded address layout}}.
*/
boolean isUnbounded();
@Override
public OfAddress withOrder(ByteOrder order) {
Objects.requireNonNull(order);
return new OfAddress(order, bitSize(), alignment, name());
}
}
/**
* A value layout constant whose size is the same as that of a machine address ({@code size_t}),
* bit alignment set to {@code sizeof(size_t) * 8}, and byte order set to {@link ByteOrder#nativeOrder()}.
* bit alignment set to {@code sizeof(size_t) * 8}, byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(MemoryAddress.class, ByteOrder.nativeOrder())
* .withBitAlignment(<address size>);
* MemoryLayout.valueLayout(MemorySegment.class, ByteOrder.nativeOrder());
* }
*/
public static final OfAddress ADDRESS = new OfAddress(ByteOrder.nativeOrder())
.withBitAlignment(ValueLayout.ADDRESS_SIZE_BITS);
OfAddress ADDRESS = ValueLayouts.OfAddressImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code byte},
* bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder()).withBitAlignment(8);
* MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder());
* }
*/
public static final OfByte JAVA_BYTE = new OfByte(ByteOrder.nativeOrder()).withBitAlignment(8);
OfByte JAVA_BYTE = ValueLayouts.OfByteImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code boolean},
* bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder()).withBitAlignment(8);
* MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder());
* }
*/
public static final OfBoolean JAVA_BOOLEAN = new OfBoolean(ByteOrder.nativeOrder()).withBitAlignment(8);
OfBoolean JAVA_BOOLEAN = ValueLayouts.OfBooleanImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code char},
* bit alignment set to 16, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder()).withBitAlignment(16);
* MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder());
* }
*/
public static final OfChar JAVA_CHAR = new OfChar(ByteOrder.nativeOrder()).withBitAlignment(16);
OfChar JAVA_CHAR = ValueLayouts.OfCharImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code short},
* bit alignment set to 16, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder()).withBitAlignment(16);
* MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder());
* }
*/
public static final OfShort JAVA_SHORT = new OfShort(ByteOrder.nativeOrder()).withBitAlignment(16);
OfShort JAVA_SHORT = ValueLayouts.OfShortImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code int},
* bit alignment set to 32, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder()).withBitAlignment(32);
* MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder());
* }
*/
public static final OfInt JAVA_INT = new OfInt(ByteOrder.nativeOrder()).withBitAlignment(32);
OfInt JAVA_INT = ValueLayouts.OfIntImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code long},
* bit alignment set to 64, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder()).withBitAlignment(64);
* MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder());
* }
*/
public static final OfLong JAVA_LONG = new OfLong(ByteOrder.nativeOrder())
.withBitAlignment(64);
OfLong JAVA_LONG = ValueLayouts.OfLongImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code float},
@ -685,15 +514,100 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout {
* MemoryLayout.valueLayout(float.class, ByteOrder.nativeOrder()).withBitAlignment(32);
* }
*/
public static final OfFloat JAVA_FLOAT = new OfFloat(ByteOrder.nativeOrder()).withBitAlignment(32);
OfFloat JAVA_FLOAT = ValueLayouts.OfFloatImpl.of(ByteOrder.nativeOrder());
/**
* A value layout constant whose size is the same as that of a Java {@code double},
* bit alignment set to 64, and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder()).withBitAlignment(64);
* MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder());
* }
*/
public static final OfDouble JAVA_DOUBLE = new OfDouble(ByteOrder.nativeOrder()).withBitAlignment(64);
OfDouble JAVA_DOUBLE = ValueLayouts.OfDoubleImpl.of(ByteOrder.nativeOrder());
/**
* An unaligned value layout constant whose size is the same as that of a machine address ({@code size_t}),
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* ADDRESS.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfAddress ADDRESS_UNALIGNED = ADDRESS.withBitAlignment(8);
/**
* An unaligned value layout constant whose size is the same as that of a Java {@code char}
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* JAVA_CHAR.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfChar JAVA_CHAR_UNALIGNED = JAVA_CHAR.withBitAlignment(8);
/**
* An unaligned value layout constant whose size is the same as that of a Java {@code short}
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* JAVA_SHORT.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfShort JAVA_SHORT_UNALIGNED = JAVA_SHORT.withBitAlignment(8);
/**
* An unaligned value layout constant whose size is the same as that of a Java {@code int}
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* JAVA_INT.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfInt JAVA_INT_UNALIGNED = JAVA_INT.withBitAlignment(8);
/**
* An unaligned value layout constant whose size is the same as that of a Java {@code long}
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* JAVA_LONG.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfLong JAVA_LONG_UNALIGNED = JAVA_LONG.withBitAlignment(8);
/**
* An unaligned value layout constant whose size is the same as that of a Java {@code float}
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* JAVA_FLOAT.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfFloat JAVA_FLOAT_UNALIGNED = JAVA_FLOAT.withBitAlignment(8);
/**
* An unaligned value layout constant whose size is the same as that of a Java {@code double}
* and byte order set to {@link ByteOrder#nativeOrder()}.
* Equivalent to the following code:
* {@snippet lang=java :
* JAVA_DOUBLE.withBitAlignment(8);
* }
* @apiNote Care should be taken when using unaligned value layouts as they may induce
* performance and portability issues.
*/
OfDouble JAVA_DOUBLE_UNALIGNED = JAVA_DOUBLE.withBitAlignment(8);
}