/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package jdk.internal.foreign;
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.ValueLayout;
import java.nio.ByteOrder;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
import static jdk.incubator.foreign.MemoryLayouts.ADDRESS;
public class PlatformLayouts {
public static <Z extends MemoryLayout> Z pick(Z sysv, Z win64, Z aarch64) {
return switch (CABI.current()) {
case SysV -> sysv;
case Win64 -> win64;
case AArch64 -> aarch64;
};
}
public static MemoryLayout asVarArg(MemoryLayout ml) {
if (CABI.current() == CABI.Win64) {
return Win64.asVarArg(ml);
}
return ml;
}
private static ValueLayout ofChar(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.CHAR);
}
private static ValueLayout ofShort(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.SHORT);
}
private static ValueLayout ofInt(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.INT);
}
private static ValueLayout ofLong(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONG);
}
private static ValueLayout ofLongLong(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONG_LONG);
}
private static ValueLayout ofFloat(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.FLOAT);
}
private static ValueLayout ofDouble(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.DOUBLE);
}
private static ValueLayout ofPointer(ByteOrder order, long bitSize) {
return MemoryLayout.ofValueBits(bitSize, order)
.withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.POINTER);
}
public static CLinker.TypeKind getKind(MemoryLayout layout) {
return (CLinker.TypeKind)layout.attribute(CLinker.TypeKind.ATTR_NAME).orElseThrow(
() -> new IllegalStateException("Unexpected value layout: could not determine ABI class"));
}
This class defines layout constants modelling standard primitive types supported by the x64 SystemV ABI.
/**
* This class defines layout constants modelling standard primitive types supported by the x64 SystemV ABI.
*/
public static final class SysV {
private SysV() {
//just the one
}
The char
native type. /**
* The {@code char} native type.
*/
public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
The short
native type. /**
* The {@code short} native type.
*/
public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
The int
native type. /**
* The {@code int} native type.
*/
public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
The long
native type. /**
* The {@code long} native type.
*/
public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64);
The long long
native type. /**
* The {@code long long} native type.
*/
public static final ValueLayout C_LONG_LONG = ofLongLong(LITTLE_ENDIAN, 64);
The float
native type. /**
* The {@code float} native type.
*/
public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
The double
native type. /**
* The {@code double} native type.
*/
public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
The T*
native type. /**
* The {@code T*} native type.
*/
public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, 64);
The va_list
native type, as it is passed to a function. /**
* The {@code va_list} native type, as it is passed to a function.
*/
public static final MemoryLayout C_VA_LIST = SysV.C_POINTER;
}
This class defines layout constants modelling standard primitive types supported by the x64 Windows ABI.
/**
* This class defines layout constants modelling standard primitive types supported by the x64 Windows ABI.
*/
public static final class Win64 {
private Win64() {
//just the one
}
The name of the layout attribute (see MemoryLayout.attributes()
used to mark variadic parameters. The attribute value must be a boolean. /**
* The name of the layout attribute (see {@link MemoryLayout#attributes()} used to mark variadic parameters. The
* attribute value must be a boolean.
*/
public final static String VARARGS_ATTRIBUTE_NAME = "abi/windows/varargs";
The char
native type. /**
* The {@code char} native type.
*/
public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
The short
native type. /**
* The {@code short} native type.
*/
public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
The int
native type. /**
* The {@code int} native type.
*/
public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
The long
native type. /**
* The {@code long} native type.
*/
public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 32);
The long long
native type. /**
* The {@code long long} native type.
*/
public static final ValueLayout C_LONG_LONG = ofLongLong(LITTLE_ENDIAN, 64);
The float
native type. /**
* The {@code float} native type.
*/
public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
The double
native type. /**
* The {@code double} native type.
*/
public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
The T*
native type. /**
* The {@code T*} native type.
*/
public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, 64);
The va_list
native type, as it is passed to a function. /**
* The {@code va_list} native type, as it is passed to a function.
*/
public static final MemoryLayout C_VA_LIST = Win64.C_POINTER;
Return a new memory layout which describes a variadic parameter to be passed to a function.
Params: - layout – the original parameter layout.
Returns: a layout which is the same as layout
, except for the extra attribute VARARGS_ATTRIBUTE_NAME
, which is set to true
.
/**
* Return a new memory layout which describes a variadic parameter to be passed to a function.
* @param layout the original parameter layout.
* @return a layout which is the same as {@code layout}, except for the extra attribute {@link #VARARGS_ATTRIBUTE_NAME},
* which is set to {@code true}.
*/
public static MemoryLayout asVarArg(MemoryLayout layout) {
return layout.withAttribute(VARARGS_ATTRIBUTE_NAME, true);
}
}
This class defines layout constants modelling standard primitive types supported by the AArch64 ABI.
/**
* This class defines layout constants modelling standard primitive types supported by the AArch64 ABI.
*/
public static final class AArch64 {
private AArch64() {
//just the one
}
The char
native type. /**
* The {@code char} native type.
*/
public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8);
The short
native type. /**
* The {@code short} native type.
*/
public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16);
The int
native type. /**
* The {@code int} native type.
*/
public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32);
The long
native type. /**
* The {@code long} native type.
*/
public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64);
The long long
native type. /**
* The {@code long long} native type.
*/
public static final ValueLayout C_LONG_LONG = ofLongLong(LITTLE_ENDIAN, 64);
The float
native type. /**
* The {@code float} native type.
*/
public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32);
The double
native type. /**
* The {@code double} native type.
*/
public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64);
The T*
native type. /**
* The {@code T*} native type.
*/
public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, 64);
The va_list
native type, as it is passed to a function. /**
* The {@code va_list} native type, as it is passed to a function.
*/
public static final MemoryLayout C_VA_LIST = AArch64.C_POINTER;
}
}