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 package jdk.internal.foreign.abi.x64.windows;
26
27 import jdk.incubator.foreign.CSupport;
28 import jdk.incubator.foreign.ForeignLinker;
29 import jdk.incubator.foreign.FunctionDescriptor;
30 import jdk.incubator.foreign.MemoryAddress;
31 import jdk.incubator.foreign.MemoryLayout;
32 import jdk.incubator.foreign.MemorySegment;
33 import jdk.internal.foreign.abi.UpcallStubs;
34
35 import java.lang.invoke.MethodHandle;
36 import java.lang.invoke.MethodHandles;
37 import java.lang.invoke.MethodType;
38 import java.util.function.Consumer;
39
40 import static jdk.incubator.foreign.CSupport.*;
41
42 /**
43 * ABI implementation based on Windows ABI AMD64 supplement v.0.99.6
44 */
45 public class Windowsx64Linker implements ForeignLinker {
46
47 public static final int MAX_INTEGER_ARGUMENT_REGISTERS = 4;
48 public static final int MAX_INTEGER_RETURN_REGISTERS = 1;
49 public static final int MAX_VECTOR_ARGUMENT_REGISTERS = 4;
50 public static final int MAX_VECTOR_RETURN_REGISTERS = 1;
51 public static final int MAX_REGISTER_ARGUMENTS = 4;
52 public static final int MAX_REGISTER_RETURNS = 1;
53
54 private static Windowsx64Linker instance;
55
56 static final long ADDRESS_SIZE = 64; // bits
57
58 private static final MethodHandle MH_unboxVaList;
59 private static final MethodHandle MH_boxVaList;
60
61 static {
62 try {
63 MethodHandles.Lookup lookup = MethodHandles.lookup();
64 MH_unboxVaList = lookup.findStatic(Windowsx64Linker.class, "unboxVaList",
65 MethodType.methodType(MemoryAddress.class, CSupport.VaList.class));
66 MH_boxVaList = lookup.findStatic(Windowsx64Linker.class, "boxVaList",
67 MethodType.methodType(VaList.class, MemoryAddress.class));
68 } catch (ReflectiveOperationException e) {
69 throw new ExceptionInInitializerError(e);
70 }
71 }
72
73 public static Windowsx64Linker getInstance() {
74 if (instance == null) {
75 instance = new Windowsx64Linker();
76 }
77 return instance;
78 }
79
80 public static VaList newVaList(Consumer<VaList.Builder> actions) {
81 WinVaList.Builder builder = WinVaList.builder();
82 actions.accept(builder);
83 return builder.build();
84 }
85
86 private static MethodType convertVaListCarriers(MethodType mt) {
87 Class<?>[] params = new Class<?>[mt.parameterCount()];
88 for (int i = 0; i < params.length; i++) {
89 Class<?> pType = mt.parameterType(i);
90 params[i] = ((pType == CSupport.VaList.class) ? WinVaList.CARRIER : pType);
91 }
92 return MethodType.methodType(mt.returnType(), params);
93 }
94
95 private static MethodHandle unxboxVaLists(MethodType type, MethodHandle handle) {
96 for (int i = 0; i < type.parameterCount(); i++) {
97 if (type.parameterType(i) == VaList.class) {
98 handle = MethodHandles.filterArguments(handle, i, MH_unboxVaList);
99 }
100 }
101 return handle;
102 }
103
104 @Override
105 public MethodHandle downcallHandle(MemoryAddress symbol, MethodType type, FunctionDescriptor function) {
106 MethodType llMt = convertVaListCarriers(type);
107 MethodHandle handle = CallArranger.arrangeDowncall(symbol, llMt, function);
108 handle = unxboxVaLists(type, handle);
109 return handle;
110 }
111
112 private static MethodHandle boxVaLists(MethodHandle handle) {
113 MethodType type = handle.type();
114 for (int i = 0; i < type.parameterCount(); i++) {
115 if (type.parameterType(i) == VaList.class) {
116 handle = MethodHandles.filterArguments(handle, i, MH_boxVaList);
117 }
118 }
119 return handle;
120 }
121
122 @Override
123 public MemorySegment upcallStub(MethodHandle target, FunctionDescriptor function) {
124 target = boxVaLists(target);
125 return UpcallStubs.upcallAddress(CallArranger.arrangeUpcall(target, target.type(), function));
126 }
127
128 @Override
129 public String name() {
130 return Win64.NAME;
131 }
132
133 static Win64.ArgumentClass argumentClassFor(MemoryLayout layout) {
134 return (Win64.ArgumentClass)layout.attribute(Win64.CLASS_ATTRIBUTE_NAME).get();
135 }
136
137 private static MemoryAddress unboxVaList(CSupport.VaList list) {
138 return ((WinVaList) list).getSegment().baseAddress();
139 }
140
141 private static CSupport.VaList boxVaList(MemoryAddress ma) {
142 return WinVaList.ofAddress(ma);
143 }
144
145 public static VaList newVaListOfAddress(MemoryAddress ma) {
146 return WinVaList.ofAddress(ma);
147 }
148
149 }
|
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 package jdk.internal.foreign.abi.x64.windows;
26
27 import jdk.incubator.foreign.CSupport;
28 import jdk.incubator.foreign.ForeignLinker;
29 import jdk.incubator.foreign.FunctionDescriptor;
30 import jdk.incubator.foreign.MemoryAddress;
31 import jdk.incubator.foreign.MemoryLayout;
32 import jdk.incubator.foreign.MemorySegment;
33 import jdk.internal.foreign.abi.SharedUtils;
34 import jdk.internal.foreign.abi.UpcallStubs;
35
36 import java.lang.invoke.MethodHandle;
37 import java.lang.invoke.MethodHandles;
38 import java.lang.invoke.MethodType;
39 import java.util.function.Consumer;
40
41 import static jdk.incubator.foreign.CSupport.*;
42
43 /**
44 * ABI implementation based on Windows ABI AMD64 supplement v.0.99.6
45 */
46 public class Windowsx64Linker implements ForeignLinker {
47
48 public static final int MAX_INTEGER_ARGUMENT_REGISTERS = 4;
49 public static final int MAX_INTEGER_RETURN_REGISTERS = 1;
50 public static final int MAX_VECTOR_ARGUMENT_REGISTERS = 4;
51 public static final int MAX_VECTOR_RETURN_REGISTERS = 1;
52 public static final int MAX_REGISTER_ARGUMENTS = 4;
53 public static final int MAX_REGISTER_RETURNS = 1;
54
55 private static Windowsx64Linker instance;
56
57 static final long ADDRESS_SIZE = 64; // bits
58
59 private static final MethodHandle MH_unboxVaList;
60 private static final MethodHandle MH_boxVaList;
61
62 static {
63 try {
64 MethodHandles.Lookup lookup = MethodHandles.lookup();
65 MH_unboxVaList = lookup.findVirtual(CSupport.VaList.class, "address",
66 MethodType.methodType(MemoryAddress.class));
67 MH_boxVaList = lookup.findStatic(Windowsx64Linker.class, "newVaListOfAddress",
68 MethodType.methodType(VaList.class, MemoryAddress.class));
69 } catch (ReflectiveOperationException e) {
70 throw new ExceptionInInitializerError(e);
71 }
72 }
73
74 public static Windowsx64Linker getInstance() {
75 if (instance == null) {
76 instance = new Windowsx64Linker();
77 }
78 return instance;
79 }
80
81 public static VaList newVaList(Consumer<VaList.Builder> actions) {
82 WinVaList.Builder builder = WinVaList.builder();
83 actions.accept(builder);
84 return builder.build();
85 }
86
87 @Override
88 public MethodHandle downcallHandle(MemoryAddress symbol, MethodType type, FunctionDescriptor function) {
89 MethodType llMt = SharedUtils.convertVaListCarriers(type, WinVaList.CARRIER);
90 MethodHandle handle = CallArranger.arrangeDowncall(symbol, llMt, function);
91 handle = SharedUtils.unboxVaLists(type, handle, MH_unboxVaList);
92 return handle;
93 }
94
95 @Override
96 public MemorySegment upcallStub(MethodHandle target, FunctionDescriptor function) {
97 target = SharedUtils.boxVaLists(target, MH_boxVaList);
98 return UpcallStubs.upcallAddress(CallArranger.arrangeUpcall(target, target.type(), function));
99 }
100
101 @Override
102 public String name() {
103 return Win64.NAME;
104 }
105
106 static Win64.ArgumentClass argumentClassFor(MemoryLayout layout) {
107 return (Win64.ArgumentClass)layout.attribute(Win64.CLASS_ATTRIBUTE_NAME).get();
108 }
109
110 public static VaList newVaListOfAddress(MemoryAddress ma) {
111 return WinVaList.ofAddress(ma);
112 }
113
114 public static VaList emptyVaList() {
115 return WinVaList.empty();
116 }
117 }
|