1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 package jdk.internal.foreign; 27 28 import jdk.incubator.foreign.CLinker; 29 import jdk.incubator.foreign.MemoryLayout; 30 import jdk.incubator.foreign.ValueLayout; 31 32 import java.nio.ByteOrder; 33 34 import static java.nio.ByteOrder.LITTLE_ENDIAN; 35 import static jdk.incubator.foreign.MemoryLayouts.ADDRESS; 36 37 public class PlatformLayouts { pick(Z sysv, Z win64, Z aarch64)38 public static <Z extends MemoryLayout> Z pick(Z sysv, Z win64, Z aarch64) { 39 return switch (CABI.current()) { 40 case SysV -> sysv; 41 case Win64 -> win64; 42 case AArch64 -> aarch64; 43 }; 44 } 45 asVarArg(MemoryLayout ml)46 public static MemoryLayout asVarArg(MemoryLayout ml) { 47 if (CABI.current() == CABI.Win64) { 48 return Win64.asVarArg(ml); 49 } 50 return ml; 51 } 52 ofChar(ByteOrder order, long bitSize)53 private static ValueLayout ofChar(ByteOrder order, long bitSize) { 54 return MemoryLayout.ofValueBits(bitSize, order) 55 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.CHAR); 56 } 57 ofShort(ByteOrder order, long bitSize)58 private static ValueLayout ofShort(ByteOrder order, long bitSize) { 59 return MemoryLayout.ofValueBits(bitSize, order) 60 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.SHORT); 61 } 62 ofInt(ByteOrder order, long bitSize)63 private static ValueLayout ofInt(ByteOrder order, long bitSize) { 64 return MemoryLayout.ofValueBits(bitSize, order) 65 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.INT); 66 } 67 ofLong(ByteOrder order, long bitSize)68 private static ValueLayout ofLong(ByteOrder order, long bitSize) { 69 return MemoryLayout.ofValueBits(bitSize, order) 70 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONG); 71 } 72 ofLongLong(ByteOrder order, long bitSize)73 private static ValueLayout ofLongLong(ByteOrder order, long bitSize) { 74 return MemoryLayout.ofValueBits(bitSize, order) 75 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.LONG_LONG); 76 } 77 ofFloat(ByteOrder order, long bitSize)78 private static ValueLayout ofFloat(ByteOrder order, long bitSize) { 79 return MemoryLayout.ofValueBits(bitSize, order) 80 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.FLOAT); 81 } 82 ofDouble(ByteOrder order, long bitSize)83 private static ValueLayout ofDouble(ByteOrder order, long bitSize) { 84 return MemoryLayout.ofValueBits(bitSize, order) 85 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.DOUBLE); 86 } 87 ofPointer(ByteOrder order, long bitSize)88 private static ValueLayout ofPointer(ByteOrder order, long bitSize) { 89 return MemoryLayout.ofValueBits(bitSize, order) 90 .withAttribute(CLinker.TypeKind.ATTR_NAME, CLinker.TypeKind.POINTER); 91 } 92 getKind(MemoryLayout layout)93 public static CLinker.TypeKind getKind(MemoryLayout layout) { 94 return (CLinker.TypeKind)layout.attribute(CLinker.TypeKind.ATTR_NAME).orElseThrow( 95 () -> new IllegalStateException("Unexpected value layout: could not determine ABI class")); 96 } 97 98 /** 99 * This class defines layout constants modelling standard primitive types supported by the x64 SystemV ABI. 100 */ 101 public static final class SysV { SysV()102 private SysV() { 103 //just the one 104 } 105 106 /** 107 * The {@code char} native type. 108 */ 109 public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8); 110 111 /** 112 * The {@code short} native type. 113 */ 114 public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16); 115 116 /** 117 * The {@code int} native type. 118 */ 119 public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32); 120 121 /** 122 * The {@code long} native type. 123 */ 124 public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64); 125 126 /** 127 * The {@code long long} native type. 128 */ 129 public static final ValueLayout C_LONG_LONG = ofLongLong(LITTLE_ENDIAN, 64); 130 131 /** 132 * The {@code float} native type. 133 */ 134 public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32); 135 136 /** 137 * The {@code double} native type. 138 */ 139 public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64); 140 141 /** 142 * The {@code T*} native type. 143 */ 144 public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, 64); 145 146 /** 147 * The {@code va_list} native type, as it is passed to a function. 148 */ 149 public static final MemoryLayout C_VA_LIST = SysV.C_POINTER; 150 } 151 152 /** 153 * This class defines layout constants modelling standard primitive types supported by the x64 Windows ABI. 154 */ 155 public static final class Win64 { 156 Win64()157 private Win64() { 158 //just the one 159 } 160 161 /** 162 * The name of the layout attribute (see {@link MemoryLayout#attributes()} used to mark variadic parameters. The 163 * attribute value must be a boolean. 164 */ 165 public final static String VARARGS_ATTRIBUTE_NAME = "abi/windows/varargs"; 166 167 /** 168 * The {@code char} native type. 169 */ 170 public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8); 171 172 /** 173 * The {@code short} native type. 174 */ 175 public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16); 176 177 /** 178 * The {@code int} native type. 179 */ 180 public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32); 181 /** 182 * The {@code long} native type. 183 */ 184 public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 32); 185 186 /** 187 * The {@code long long} native type. 188 */ 189 public static final ValueLayout C_LONG_LONG = ofLongLong(LITTLE_ENDIAN, 64); 190 191 /** 192 * The {@code float} native type. 193 */ 194 public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32); 195 196 /** 197 * The {@code double} native type. 198 */ 199 public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64); 200 201 /** 202 * The {@code T*} native type. 203 */ 204 public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, 64); 205 206 /** 207 * The {@code va_list} native type, as it is passed to a function. 208 */ 209 public static final MemoryLayout C_VA_LIST = Win64.C_POINTER; 210 211 /** 212 * Return a new memory layout which describes a variadic parameter to be passed to a function. 213 * @param layout the original parameter layout. 214 * @return a layout which is the same as {@code layout}, except for the extra attribute {@link #VARARGS_ATTRIBUTE_NAME}, 215 * which is set to {@code true}. 216 */ asVarArg(MemoryLayout layout)217 public static MemoryLayout asVarArg(MemoryLayout layout) { 218 return layout.withAttribute(VARARGS_ATTRIBUTE_NAME, true); 219 } 220 } 221 222 /** 223 * This class defines layout constants modelling standard primitive types supported by the AArch64 ABI. 224 */ 225 public static final class AArch64 { 226 AArch64()227 private AArch64() { 228 //just the one 229 } 230 231 /** 232 * The {@code char} native type. 233 */ 234 public static final ValueLayout C_CHAR = ofChar(LITTLE_ENDIAN, 8); 235 236 /** 237 * The {@code short} native type. 238 */ 239 public static final ValueLayout C_SHORT = ofShort(LITTLE_ENDIAN, 16); 240 241 /** 242 * The {@code int} native type. 243 */ 244 public static final ValueLayout C_INT = ofInt(LITTLE_ENDIAN, 32); 245 246 /** 247 * The {@code long} native type. 248 */ 249 public static final ValueLayout C_LONG = ofLong(LITTLE_ENDIAN, 64); 250 251 /** 252 * The {@code long long} native type. 253 */ 254 public static final ValueLayout C_LONG_LONG = ofLongLong(LITTLE_ENDIAN, 64); 255 256 /** 257 * The {@code float} native type. 258 */ 259 public static final ValueLayout C_FLOAT = ofFloat(LITTLE_ENDIAN, 32); 260 261 /** 262 * The {@code double} native type. 263 */ 264 public static final ValueLayout C_DOUBLE = ofDouble(LITTLE_ENDIAN, 64); 265 266 /** 267 * The {@code T*} native type. 268 */ 269 public static final ValueLayout C_POINTER = ofPointer(LITTLE_ENDIAN, 64); 270 271 /** 272 * The {@code va_list} native type, as it is passed to a function. 273 */ 274 public static final MemoryLayout C_VA_LIST = AArch64.C_POINTER; 275 } 276 } 277