Skip to content

Commit d0e35de

Browse files
author
duke
committedOct 7, 2020
Automatic merge of foreign-abi into foreign-jextract
2 parents 35d98aa + 6663aab commit d0e35de

File tree

9 files changed

+165
-275
lines changed

9 files changed

+165
-275
lines changed
 

‎src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ String decorateLayoutString(String s) {
150150
return s;
151151
}
152152

153-
protected <T> DynamicConstantDesc<T> decorateLayoutConstant(DynamicConstantDesc<T> desc) {
153+
<T> DynamicConstantDesc<T> decorateLayoutConstant(DynamicConstantDesc<T> desc) {
154154
if (!hasNaturalAlignment()) {
155155
desc = DynamicConstantDesc.ofNamed(BSM_INVOKE, "withBitAlignment", desc.constantType(), MH_WITH_BIT_ALIGNMENT,
156156
desc, bitAlignment());
@@ -163,7 +163,7 @@ protected <T> DynamicConstantDesc<T> decorateLayoutConstant(DynamicConstantDesc<
163163
return desc;
164164
}
165165

166-
protected boolean hasNaturalAlignment() {
166+
boolean hasNaturalAlignment() {
167167
return size.isPresent() && size.getAsLong() == alignment;
168168
}
169169

‎src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/CLinker.java

+84-192
Original file line numberDiff line numberDiff line change
@@ -31,44 +31,42 @@
3131
import jdk.internal.foreign.abi.SharedUtils;
3232

3333
import java.lang.constant.Constable;
34-
import java.lang.constant.DynamicConstantDesc;
3534
import java.lang.invoke.MethodHandle;
3635
import java.lang.invoke.MethodType;
37-
import java.nio.ByteOrder;
3836
import java.nio.charset.Charset;
39-
import java.util.Map;
4037
import java.util.Objects;
41-
import java.util.Optional;
4238
import java.util.function.Consumer;
4339

44-
import static java.lang.constant.ConstantDescs.BSM_GET_STATIC_FINAL;
4540
import static jdk.internal.foreign.PlatformLayouts.*;
4641

4742
/**
4843
* A foreign linker specializing for C Application Binary Interface (ABI) calling conventions.
4944
* Instances of this interface can be used to link foreign functions in native libraries that
5045
* follow the JVM's target platform C ABI.
51-
*
52-
* <p>There are two components that go into linking a foreign function: a method type, and
46+
* <p>
47+
* There are two components that go into linking a foreign function: a method type, and
5348
* a function descriptor. The method type, consists of a set of <em>carrier</em> types, which, together,
5449
* specify the Java signature which clients must adhere to when calling the underlying foreign function.
5550
* The function descriptor contains a set of memory layouts which, together, specify the foreign function
56-
* signature and classification information (via custom layout attributes), so that linking can take place.
57-
* Memory layout attributes are used in the function descriptor to attach ABI classification meta-data to
58-
* memory layouts, which are required for linking. Clients of this API should build function descriptors
59-
* using the predefined memory layout constants (based on a subset of the built-in types provided by the C language),
60-
* found in this interface; a failure to do so might result in linkage errors, given that linking requires additional
61-
* classification information to determine, for instance, how arguments should be loaded into registers during a
62-
* foreign function call.</p>
63-
*
64-
* <p>Implementations of this interface support the following primitive carrier types:
51+
* signature and classification information (via a custom layout attributes, see {@link TypeKind}), so that linking can take place.
52+
* Memory layout attributes are used in the function descriptor to attach ABI classification meta-data to memory layouts,
53+
* which are required for linking.
54+
* <p>
55+
* Clients of this API can build function descriptors using the predefined memory layout constants
56+
* (based on a subset of the built-in types provided by the C language), found in this interface; alternatively,
57+
* they can also decorate existing value layouts using the required {@link TypeKind} classification attribute
58+
* (this can be done using the {@link MemoryLayout#withAttribute(String, Constable)} method). A failure to do so might
59+
* result in linkage errors, given that linking requires additional classification information to determine, for instance,
60+
* how arguments should be loaded into registers during a foreign function call.
61+
* <p>
62+
* Implementations of this interface support the following primitive carrier types:
6563
* {@code byte}, {@code short}, {@code char}, {@code int}, {@code long}, {@code float},
6664
* and {@code double}, as well as {@link MemoryAddress} for passing pointers, and
6765
* {@link MemorySegment} for passing structs and unions. Finally, the {@link VaList}
68-
* carrier type can be used to match the native {@code va_list} type.</p>
69-
*
70-
* <p>The function descriptor used in linking contains a memory layout to match each carrier type.
71-
* There are some restrictions on the carrier type and memory layout combinations that are allowed:</p>
66+
* carrier type can be used to match the native {@code va_list} type.
67+
* <p>
68+
* The function descriptor used in linking contains a memory layout to match each carrier type.
69+
* There are some restrictions on the carrier type and memory layout combinations that are allowed:
7270
* <ul>
7371
* <li>If a primitve type is used as a carrier type, the corresponding
7472
* memory layout must be a {@code ValueLayout}, and the bit size of the layout must match that of the carrier type
@@ -94,7 +92,7 @@
9492
* function descriptor when linking the function. Furthermore, as memory layouts corresponding to variadic arguments in
9593
* a function descriptor must contain additional classification information, it is required that
9694
* {@link #asVarArg(MemoryLayout)} is used to create the memory layouts for each parameter corresponding to a variadic
97-
* argument in a specialized function descriptor</p>
95+
* argument in a specialized function descriptor
9896
*
9997
* @apiNote In the future, if the Java language permits, {@link MemoryLayout}
10098
* may become a {@code sealed} interface, which would prohibit subclassing except by
@@ -151,39 +149,39 @@ static CLinker getInstance() {
151149
/**
152150
* The layout for the {@code char} C type
153151
*/
154-
CValueLayout C_CHAR = pick(SysV.C_CHAR, Win64.C_CHAR, AArch64.C_CHAR);
152+
ValueLayout C_CHAR = pick(SysV.C_CHAR, Win64.C_CHAR, AArch64.C_CHAR);
155153
/**
156154
* The layout for the {@code short} C type
157155
*/
158-
CValueLayout C_SHORT = pick(SysV.C_SHORT, Win64.C_SHORT, AArch64.C_SHORT);
156+
ValueLayout C_SHORT = pick(SysV.C_SHORT, Win64.C_SHORT, AArch64.C_SHORT);
159157
/**
160158
* The layout for the {@code int} C type
161159
*/
162-
CValueLayout C_INT = pick(SysV.C_INT, Win64.C_INT, AArch64.C_INT);
160+
ValueLayout C_INT = pick(SysV.C_INT, Win64.C_INT, AArch64.C_INT);
163161
/**
164162
* The layout for the {@code long} C type
165163
*/
166-
CValueLayout C_LONG = pick(SysV.C_LONG, Win64.C_LONG, AArch64.C_LONG);
164+
ValueLayout C_LONG = pick(SysV.C_LONG, Win64.C_LONG, AArch64.C_LONG);
167165
/**
168166
* The {@code long long} native type.
169167
*/
170-
CValueLayout C_LONGLONG = pick(SysV.C_LONGLONG, Win64.C_LONGLONG, AArch64.C_LONGLONG);
168+
ValueLayout C_LONGLONG = pick(SysV.C_LONGLONG, Win64.C_LONGLONG, AArch64.C_LONGLONG);
171169
/**
172170
* The layout for the {@code float} C type
173171
*/
174-
CValueLayout C_FLOAT = pick(SysV.C_FLOAT, Win64.C_FLOAT, AArch64.C_FLOAT);
172+
ValueLayout C_FLOAT = pick(SysV.C_FLOAT, Win64.C_FLOAT, AArch64.C_FLOAT);
175173
/**
176174
* The layout for the {@code double} C type
177175
*/
178-
CValueLayout C_DOUBLE = pick(SysV.C_DOUBLE, Win64.C_DOUBLE, AArch64.C_DOUBLE);
176+
ValueLayout C_DOUBLE = pick(SysV.C_DOUBLE, Win64.C_DOUBLE, AArch64.C_DOUBLE);
179177
/**
180178
* The {@code long double} native type.
181179
*/
182-
CValueLayout C_LONGDOUBLE = pick(SysV.C_LONGDOUBLE, Win64.C_LONGDOUBLE, AArch64.C_LONGDOUBLE);
180+
ValueLayout C_LONGDOUBLE = pick(SysV.C_LONGDOUBLE, Win64.C_LONGDOUBLE, AArch64.C_LONGDOUBLE);
183181
/**
184182
* The {@code T*} native type.
185183
*/
186-
CValueLayout C_POINTER = pick(SysV.C_POINTER, Win64.C_POINTER, AArch64.C_POINTER);
184+
ValueLayout C_POINTER = pick(SysV.C_POINTER, Win64.C_POINTER, AArch64.C_POINTER);
187185
/**
188186
* The layout for the {@code va_list} C type
189187
*/
@@ -707,196 +705,90 @@ interface Builder {
707705
}
708706

709707
/**
710-
* Subclass of {@link ValueLayout} that contains information needed when linking
711-
* downcalls or upcalls.
708+
* A C type kind. Each kind corresponds to a particular C language builtin type, and can be attached to
709+
* {@link ValueLayout} instances using the {@link MemoryLayout#withAttribute(String, Constable)} in order
710+
* to obtain a layout which can be classified accordingly by {@link CLinker#downcallHandle(Addressable, MethodType, FunctionDescriptor)}
711+
* and {@link CLinker#upcallStub(MethodHandle, FunctionDescriptor)}.
712712
*/
713-
class CValueLayout extends ValueLayout {
713+
enum TypeKind {
714714
/**
715-
* The kind of {@link CValueLayout}. Each kind corresponds to a particular
716-
* C language builtin type.
715+
* A kind corresponding to the C {@code char} type
717716
*/
718-
public enum Kind {
719-
/**
720-
* A kind corresponding to the C {@code char} type
721-
*/
722-
CHAR(findBSM("C_CHAR"), true),
723-
/**
724-
* A kind corresponding to the C {@code short} type
725-
*/
726-
SHORT(findBSM("C_SHORT"), true),
727-
/**
728-
* A kind corresponding to the C {@code int} type
729-
*/
730-
INT(findBSM("C_INT"), true),
731-
/**
732-
* A kind corresponding to the C {@code long} type
733-
*/
734-
LONG(findBSM("C_LONG"), true),
735-
/**
736-
* A kind corresponding to the C {@code long long} type
737-
*/
738-
LONGLONG(findBSM("C_LONGLONG"), true),
739-
/**
740-
* A kind corresponding to the C {@code float} type
741-
*/
742-
FLOAT(findBSM("C_FLOAT"), false),
743-
/**
744-
* A kind corresponding to the C {@code double} type
745-
*/
746-
DOUBLE(findBSM("C_DOUBLE"), false),
747-
/**
748-
* A kind corresponding to the C {@code long double} type
749-
*/
750-
LONGDOUBLE(findBSM("C_LONGDOUBLE"), false),
751-
/**
752-
* A kind corresponding to the a C pointer type
753-
*/
754-
POINTER(findBSM("C_POINTER"), false);
755-
756-
private final DynamicConstantDesc<ValueLayout> bsm;
757-
private final boolean isIntegral;
758-
759-
Kind(DynamicConstantDesc<ValueLayout> bsm, boolean isIntegral) {
760-
this.bsm = bsm;
761-
this.isIntegral = isIntegral;
762-
}
763-
764-
private DynamicConstantDesc<ValueLayout> bsm() {
765-
return bsm;
766-
}
767-
768-
/**
769-
* Is this kind integral?
770-
*
771-
* @return true if this kind is integral
772-
*/
773-
public boolean isIntergral() {
774-
return isIntegral;
775-
}
776-
777-
/**
778-
* Is this kind a floating point type?
779-
*
780-
* @return true if this kind is a floating point type
781-
*/
782-
public boolean isFloat() {
783-
return !isIntergral() && !isPointer();
784-
}
785-
786-
/**
787-
* Is this kind a pointer kind?
788-
*
789-
* @return true if this kind is a pointer kind
790-
*/
791-
public boolean isPointer() {
792-
return this == POINTER;
793-
}
794-
795-
private static DynamicConstantDesc<ValueLayout> findBSM(String fieldName) {
796-
return DynamicConstantDesc.ofNamed(
797-
BSM_GET_STATIC_FINAL,
798-
fieldName,
799-
CValueLayout.class.describeConstable().orElseThrow(),
800-
CLinker.class.describeConstable().orElseThrow()
801-
);
802-
}
803-
}
804-
805-
private final Kind kind;
806-
717+
CHAR(true),
807718
/**
808-
* CValueLayout constructor
809-
*
810-
* @param kind the kind of CValueLayout
811-
* @param order the byte order of the layout
812-
* @param bitSize the size, in bits, of the layout
813-
* @param bitAlignment the alignment, in bits, of the layout
814-
* @param attributes the attribute map of this layout
719+
* A kind corresponding to the C {@code short} type
815720
*/
816-
public CValueLayout(Kind kind, ByteOrder order, long bitSize, long bitAlignment,
817-
Map<String, Constable> attributes) {
818-
super(order, bitSize, bitAlignment, attributes);
819-
this.kind = kind;
820-
}
821-
721+
SHORT(true),
822722
/**
823-
* Accessor for the kind of this layout
824-
*
825-
* @return the kind
723+
* A kind corresponding to the C {@code int} type
826724
*/
827-
public final Kind kind() {
828-
return kind;
829-
}
830-
725+
INT(true),
831726
/**
832-
* {@inheritDoc}
727+
* A kind corresponding to the C {@code long} type
833728
*/
834-
@Override
835-
public CValueLayout withOrder(ByteOrder order) {
836-
return new CValueLayout(kind, order, bitSize(), alignment, attributes);
837-
}
838-
729+
LONG(true),
839730
/**
840-
* {@inheritDoc}
731+
* A kind corresponding to the C {@code long long} type
841732
*/
842-
@Override
843-
public CValueLayout withName(String name) {
844-
return (CValueLayout) super.withName(name);
845-
}
846-
733+
LONGLONG(true),
847734
/**
848-
* {@inheritDoc}
735+
* A kind corresponding to the C {@code float} type
849736
*/
850-
@Override
851-
public CValueLayout withBitAlignment(long alignmentBits) {
852-
return (CValueLayout) super.withBitAlignment(alignmentBits);
853-
}
854-
737+
FLOAT(false),
855738
/**
856-
* {@inheritDoc}
739+
* A kind corresponding to the C {@code double} type
857740
*/
858-
@Override
859-
public CValueLayout withAttribute(String name, Constable value) {
860-
return (CValueLayout) super.withAttribute(name, value);
861-
}
741+
DOUBLE(false),
742+
/**
743+
* A kind corresponding to the C {@code long double} type
744+
*/
745+
LONGDOUBLE(false),
746+
/**
747+
* A kind corresponding to the a C pointer type
748+
*/
749+
POINTER(false);
862750

863-
@Override
864-
CValueLayout dup(long alignment, Map<String, Constable> attributes) {
865-
return new CValueLayout(kind, order(), bitSize(), alignment, attributes);
751+
private final boolean isIntegral;
752+
753+
TypeKind(boolean isIntegral) {
754+
this.isIntegral = isIntegral;
866755
}
867756

868757
/**
869-
* {@inheritDoc}
758+
* Is this kind integral?
759+
*
760+
* @return true if this kind is integral
870761
*/
871-
@Override
872-
public Optional<DynamicConstantDesc<ValueLayout>> describeConstable() {
873-
return Optional.of(decorateLayoutConstant(kind.bsm()));
762+
public boolean isIntergral() {
763+
return isIntegral;
874764
}
875765

876766
/**
877-
* {@inheritDoc}
767+
* Is this kind a floating point type?
768+
*
769+
* @return true if this kind is a floating point type
878770
*/
879-
@Override
880-
public boolean equals(Object other) {
881-
if (this == other) {
882-
return true;
883-
}
884-
if (other == null || getClass() != other.getClass()) {
885-
return false;
886-
}
887-
if (!super.equals(other)) {
888-
return false;
889-
}
890-
CValueLayout that = (CValueLayout) other;
891-
return kind == that.kind;
771+
public boolean isFloat() {
772+
return !isIntergral() && !isPointer();
892773
}
893774

894775
/**
895-
* {@inheritDoc}
776+
* Is this kind a pointer kind?
777+
*
778+
* @return true if this kind is a pointer kind
896779
*/
897-
@Override
898-
public int hashCode() {
899-
return Objects.hash(super.hashCode(), kind);
780+
public boolean isPointer() {
781+
return this == POINTER;
900782
}
783+
784+
/**
785+
* The layout attribute name associated with this classification kind. Clients can retrieve the type kind
786+
* of a layout using the following code:
787+
* <blockquote><pre>{@code
788+
ValueLayout layout = ...
789+
TypeKind = layout.attribute(TypeKind.ATTR_NAME).orElse(null);
790+
* }</pre></blockquote>
791+
*/
792+
public final static String ATTR_NAME = "abi/kind";
901793
}
902794
}

‎src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@
4848
* @implSpec
4949
* This class is immutable and thread-safe.
5050
*/
51-
public class ValueLayout extends AbstractLayout implements MemoryLayout {
51+
public final class ValueLayout extends AbstractLayout implements MemoryLayout {
5252

5353
private final ByteOrder order;
5454

55-
protected ValueLayout(ByteOrder order, long size) {
55+
ValueLayout(ByteOrder order, long size) {
5656
this(order, size, size, Map.of());
5757
}
5858

59-
protected ValueLayout(ByteOrder order, long size, long alignment, Map<String, Constable> attributes) {
59+
ValueLayout(ByteOrder order, long size, long alignment, Map<String, Constable> attributes) {
6060
super(OptionalLong.of(size), alignment, attributes);
6161
this.order = order;
6262
}
@@ -92,10 +92,10 @@ public boolean equals(Object other) {
9292
if (this == other) {
9393
return true;
9494
}
95-
if (other == null || getClass() != other.getClass()) {
95+
if (!super.equals(other)) {
9696
return false;
9797
}
98-
if (!super.equals(other)) {
98+
if (!(other instanceof ValueLayout)) {
9999
return false;
100100
}
101101
ValueLayout v = (ValueLayout)other;

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/PlatformLayouts.java

+59-54
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,10 @@
2626
package jdk.internal.foreign;
2727

2828
import jdk.incubator.foreign.CLinker;
29-
import jdk.incubator.foreign.CLinker.CValueLayout;
3029
import jdk.incubator.foreign.MemoryLayout;
3130
import jdk.incubator.foreign.ValueLayout;
3231

3332
import java.nio.ByteOrder;
34-
import java.util.Map;
3533

3634
import static java.nio.ByteOrder.LITTLE_ENDIAN;
3735
import static jdk.incubator.foreign.MemoryLayouts.ADDRESS;
@@ -52,47 +50,54 @@ public static MemoryLayout asVarArg(MemoryLayout ml) {
5250
return ml;
5351
}
5452

55-
private static CValueLayout ofChar(ByteOrder order, long bitSize) {
56-
return new CValueLayout(CValueLayout.Kind.CHAR, order, bitSize, bitSize, Map.of());
53+
private static ValueLayout ofChar(ByteOrder order, long bitSize) {
54+
return MemoryLayout.ofValueBits(bitSize, order)
55+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.CHAR);
5756
}
5857

59-
private static CValueLayout ofShort(ByteOrder order, long bitSize) {
60-
return new CValueLayout(CValueLayout.Kind.SHORT, order, bitSize, bitSize, Map.of());
58+
private static ValueLayout ofShort(ByteOrder order, long bitSize) {
59+
return MemoryLayout.ofValueBits(bitSize, order)
60+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.SHORT);
6161
}
6262

63-
private static CValueLayout ofInt(ByteOrder order, long bitSize) {
64-
return new CValueLayout(CValueLayout.Kind.INT, order, bitSize, bitSize, Map.of());
63+
private static ValueLayout ofInt(ByteOrder order, long bitSize) {
64+
return MemoryLayout.ofValueBits(bitSize, order)
65+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.INT);
6566
}
6667

67-
private static CValueLayout ofLong(ByteOrder order, long bitSize) {
68-
return new CValueLayout(CValueLayout.Kind.LONG, order, bitSize, bitSize, Map.of());
68+
private static ValueLayout ofLong(ByteOrder order, long bitSize) {
69+
return MemoryLayout.ofValueBits(bitSize, order)
70+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONG);
6971
}
7072

71-
private static CValueLayout ofLongLong(ByteOrder order, long bitSize) {
72-
return new CValueLayout(CValueLayout.Kind.LONGLONG, order, bitSize, bitSize, Map.of());
73+
private static ValueLayout ofLongLong(ByteOrder order, long bitSize) {
74+
return MemoryLayout.ofValueBits(bitSize, order)
75+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONGLONG);
7376
}
7477

75-
private static CValueLayout ofFloat(ByteOrder order, long bitSize) {
76-
return new CValueLayout(CValueLayout.Kind.FLOAT, order, bitSize, bitSize, Map.of());
78+
private static ValueLayout ofFloat(ByteOrder order, long bitSize) {
79+
return MemoryLayout.ofValueBits(bitSize, order)
80+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.FLOAT);
7781
}
7882

79-
private static CValueLayout ofDouble(ByteOrder order, long bitSize) {
80-
return new CValueLayout(CValueLayout.Kind.DOUBLE, order, bitSize, bitSize, Map.of());
83+
private static ValueLayout ofDouble(ByteOrder order, long bitSize) {
84+
return MemoryLayout.ofValueBits(bitSize, order)
85+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.DOUBLE);
8186
}
8287

83-
private static CValueLayout ofLongDouble(ByteOrder order, long bitSize) {
84-
return new CValueLayout(CValueLayout.Kind.LONGDOUBLE, order, bitSize, bitSize, Map.of());
88+
private static ValueLayout ofLongDouble(ByteOrder order, long bitSize) {
89+
return MemoryLayout.ofValueBits(bitSize, order)
90+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONGDOUBLE);
8591
}
8692

87-
/**
88-
* Creates a new CValueLayout with the {@code POINTER} kind
89-
*
90-
* @param order the byte order of the layout
91-
* @param bitSize the size, in bits, of the layout
92-
* @return the newly created CValueLayout
93-
*/
94-
public static CValueLayout ofPointer(ByteOrder order, long bitSize) {
95-
return new CValueLayout(CValueLayout.Kind.POINTER, order, bitSize, bitSize, Map.of());
93+
private static ValueLayout ofPointer(ByteOrder order, long bitSize) {
94+
return MemoryLayout.ofValueBits(bitSize, order)
95+
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.POINTER);
96+
}
97+
98+
public static CLinker.TypeKind getKind(MemoryLayout layout) {
99+
return (CLinker.TypeKind)layout.attribute(CLinker.TypeKind.ATTR_NAME).orElseThrow(
100+
() -> new IllegalStateException("Unexpected value layout: could not determine ABI class"));
96101
}
97102

98103
/**
@@ -106,47 +111,47 @@ private SysV() {
106111
/**
107112
* The {@code char} native type.
108113
*/
109-
public static final CValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
114+
public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
110115

111116
/**
112117
* The {@code short} native type.
113118
*/
114-
public static final CValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
119+
public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
115120

116121
/**
117122
* The {@code int} native type.
118123
*/
119-
public static final CValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
124+
public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
120125

121126
/**
122127
* The {@code long} native type.
123128
*/
124-
public static final CValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64);
129+
public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64);
125130

126131
/**
127132
* The {@code long long} native type.
128133
*/
129-
public static final CValueLayout C_LONGLONG = ofLongLong(LITTLE_ENDIAN, 64);
134+
public static final ValueLayout C_LONGLONG = ofLongLong(LITTLE_ENDIAN, 64);
130135

131136
/**
132137
* The {@code float} native type.
133138
*/
134-
public static final CValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
139+
public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
135140

136141
/**
137142
* The {@code double} native type.
138143
*/
139-
public static final CValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
144+
public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
140145

141146
/**
142147
* The {@code long double} native type.
143148
*/
144-
public static final CValueLayout C_LONGDOUBLE = ofLongDouble(LITTLE_ENDIAN, 128);
149+
public static final ValueLayout C_LONGDOUBLE = ofLongDouble(LITTLE_ENDIAN, 128);
145150

146151
/**
147152
* The {@code T*} native type.
148153
*/
149-
public static final CValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, ADDRESS.bitSize());
154+
public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, ADDRESS.bitSize());
150155

151156
/**
152157
* The {@code va_list} native type, as it is passed to a function.
@@ -172,46 +177,46 @@ private Win64() {
172177
/**
173178
* The {@code char} native type.
174179
*/
175-
public static final CValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
180+
public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
176181

177182
/**
178183
* The {@code short} native type.
179184
*/
180-
public static final CValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
185+
public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
181186

182187
/**
183188
* The {@code int} native type.
184189
*/
185-
public static final CValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
190+
public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
186191
/**
187192
* The {@code long} native type.
188193
*/
189-
public static final CValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 32);
194+
public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 32);
190195

191196
/**
192197
* The {@code long long} native type.
193198
*/
194-
public static final CValueLayout C_LONGLONG = ofLongLong(LITTLE_ENDIAN, 64);
199+
public static final ValueLayout C_LONGLONG = ofLongLong(LITTLE_ENDIAN, 64);
195200

196201
/**
197202
* The {@code float} native type.
198203
*/
199-
public static final CValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
204+
public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
200205

201206
/**
202207
* The {@code double} native type.
203208
*/
204-
public static final CValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
209+
public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
205210

206211
/**
207212
* The {@code long double} native type.
208213
*/
209-
public static final CValueLayout C_LONGDOUBLE = ofLongDouble(LITTLE_ENDIAN, 64);
214+
public static final ValueLayout C_LONGDOUBLE = ofLongDouble(LITTLE_ENDIAN, 64);
210215

211216
/**
212217
* The {@code T*} native type.
213218
*/
214-
public static final CValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, ADDRESS.bitSize());
219+
public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, ADDRESS.bitSize());
215220

216221
/**
217222
* The {@code va_list} native type, as it is passed to a function.
@@ -241,47 +246,47 @@ private AArch64() {
241246
/**
242247
* The {@code char} native type.
243248
*/
244-
public static final CValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
249+
public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
245250

246251
/**
247252
* The {@code short} native type.
248253
*/
249-
public static final CValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
254+
public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
250255

251256
/**
252257
* The {@code int} native type.
253258
*/
254-
public static final CValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
259+
public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
255260

256261
/**
257262
* The {@code long} native type.
258263
*/
259-
public static final CValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64);
264+
public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64);
260265

261266
/**
262267
* The {@code long long} native type.
263268
*/
264-
public static final CValueLayout C_LONGLONG = ofLongLong(LITTLE_ENDIAN, 64);
269+
public static final ValueLayout C_LONGLONG = ofLongLong(LITTLE_ENDIAN, 64);
265270

266271
/**
267272
* The {@code float} native type.
268273
*/
269-
public static final CValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
274+
public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
270275

271276
/**
272277
* The {@code double} native type.
273278
*/
274-
public static final CValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
279+
public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
275280

276281
/**
277282
* The {@code long double} native type.
278283
*/
279-
public static final CValueLayout C_LONGDOUBLE = ofLongDouble(LITTLE_ENDIAN, 128);
284+
public static final ValueLayout C_LONGDOUBLE = ofLongDouble(LITTLE_ENDIAN, 128);
280285

281286
/**
282287
* The {@code T*} native type.
283288
*/
284-
public static final CValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, ADDRESS.bitSize());
289+
public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, ADDRESS.bitSize());
285290

286291
/**
287292
* The {@code va_list} native type, as it is passed to a function.

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/aarch64/TypeClass.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
*/
2626
package jdk.internal.foreign.abi.aarch64;
2727

28-
import jdk.incubator.foreign.CLinker;
2928
import jdk.incubator.foreign.GroupLayout;
3029
import jdk.incubator.foreign.MemoryLayout;
3130
import jdk.incubator.foreign.SequenceLayout;
3231
import jdk.incubator.foreign.ValueLayout;
32+
import jdk.internal.foreign.PlatformLayouts;
3333

3434
enum TypeClass {
3535
STRUCT_REGISTER,
@@ -42,11 +42,7 @@ enum TypeClass {
4242
private static final int MAX_AGGREGATE_REGS_SIZE = 2;
4343

4444
private static TypeClass classifyValueType(ValueLayout type) {
45-
if (!(type instanceof CLinker.CValueLayout)) {
46-
throw new IllegalStateException("Unexpected value layout: could not determine ABI class");
47-
}
48-
49-
return switch (((CLinker.CValueLayout) type).kind()) {
45+
return switch (PlatformLayouts.getKind(type)) {
5046
case CHAR, SHORT, INT, LONG, LONGLONG -> INTEGER;
5147
case POINTER -> POINTER;
5248
case FLOAT, DOUBLE, LONGDOUBLE -> FLOAT;

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/sysv/TypeClass.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
*/
2525
package jdk.internal.foreign.abi.x64.sysv;
2626

27-
import jdk.incubator.foreign.CLinker;
2827
import jdk.incubator.foreign.GroupLayout;
2928
import jdk.incubator.foreign.MemoryLayout;
3029
import jdk.incubator.foreign.SequenceLayout;
3130
import jdk.incubator.foreign.ValueLayout;
31+
import jdk.internal.foreign.PlatformLayouts;
3232
import jdk.internal.foreign.Utils;
3333

3434
import java.util.ArrayList;
@@ -107,11 +107,7 @@ private static List<ArgumentClassImpl> createMemoryClassArray(long size) {
107107
}
108108

109109
private static ArgumentClassImpl argumentClassFor(MemoryLayout layout) {
110-
if (!(layout instanceof CLinker.CValueLayout)) {
111-
throw new IllegalStateException("Unexpected value layout: could not determine ABI class");
112-
}
113-
114-
return switch (((CLinker.CValueLayout) layout).kind()) {
110+
return switch (PlatformLayouts.getKind(layout)) {
115111
case CHAR, SHORT, INT, LONG, LONGLONG -> ArgumentClassImpl.INTEGER;
116112
case FLOAT, DOUBLE -> ArgumentClassImpl.SSE;
117113
case LONGDOUBLE -> ArgumentClassImpl.X87;

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/x64/windows/TypeClass.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
*/
2525
package jdk.internal.foreign.abi.x64.windows;
2626

27-
import jdk.incubator.foreign.CLinker;
2827
import jdk.incubator.foreign.GroupLayout;
2928
import jdk.incubator.foreign.MemoryLayout;
3029
import jdk.incubator.foreign.ValueLayout;
30+
import jdk.internal.foreign.PlatformLayouts;
3131

3232
import static jdk.internal.foreign.PlatformLayouts.Win64.VARARGS_ATTRIBUTE_NAME;
3333

@@ -40,10 +40,6 @@ enum TypeClass {
4040
VARARG_FLOAT;
4141

4242
private static TypeClass classifyValueType(ValueLayout type) {
43-
if (!(type instanceof CLinker.CValueLayout)) {
44-
throw new IllegalStateException("Unexpected value layout: could not determine ABI class");
45-
}
46-
4743
// No 128 bit integers in the Windows C ABI. There are __m128(i|d) intrinsic types but they act just
4844
// like a struct when passing as an argument (passed by pointer).
4945
// https://docs.microsoft.com/en-us/cpp/cpp/m128?view=vs-2019
@@ -53,7 +49,7 @@ private static TypeClass classifyValueType(ValueLayout type) {
5349
// but must be considered volatile across function calls."
5450
// https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019
5551

56-
return switch (((CLinker.CValueLayout) type).kind()) {
52+
return switch (PlatformLayouts.getKind(type)) {
5753
case CHAR, SHORT, INT, LONG, LONGLONG -> INTEGER;
5854
case POINTER -> POINTER;
5955
case FLOAT, DOUBLE, LONGDOUBLE -> {

‎test/jdk/java/foreign/NativeTestHelper.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@
2727

2828
public class NativeTestHelper {
2929

30+
static CLinker.TypeKind kind(MemoryLayout layout) {
31+
return (CLinker.TypeKind)layout.attribute(CLinker.TypeKind.ATTR_NAME).orElseThrow(
32+
() -> new IllegalStateException("Unexpected value layout: could not determine ABI class"));
33+
}
34+
3035
public static boolean isIntegral(MemoryLayout layout) {
31-
return ((CLinker.CValueLayout) layout).kind().isIntergral();
36+
return kind(layout).isIntergral();
3237
}
3338

3439
public static boolean isPointer(MemoryLayout layout) {
35-
return ((CLinker.CValueLayout) layout).kind().isPointer();
40+
return kind(layout).isPointer();
3641
}
3742
}

‎test/jdk/java/foreign/TestLayoutEquality.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public void testReconstructedEquality(ValueLayout layout) {
5252
assertEquals(newLayout.bitAlignment(), layout.bitAlignment());
5353
assertEquals(newLayout.name(), layout.name());
5454
assertEquals(newLayout.attributes().toArray().length, 0);
55-
assertEquals(layout.attributes().toArray().length, 0);
55+
assertEquals(layout.attributes().toArray().length, 1);
5656

57-
// but equals should return false, because one is a CValueLayout
57+
// but equals should return false, because one is a ValueLayout with a CLinker kind
5858
assertNotEquals(newLayout, layout);
5959
}
6060

0 commit comments

Comments
 (0)
Please sign in to comment.