mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
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:
parent
bd381886e0
commit
73baadceb6
252 changed files with 9221 additions and 7889 deletions
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue