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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.internal.foreign.abi;
24
25 import jdk.incubator.foreign.MemoryAddress;
26 import jdk.incubator.foreign.MemorySegment;
27 import jdk.internal.foreign.MemoryAddressImpl;
28 import jdk.internal.foreign.Utils;
29
30 import java.util.ArrayDeque;
31 import java.util.Deque;
32 import java.util.List;
33
34 public class BindingInterpreter {
35
36 static void unbox(Object arg, List<Binding> bindings, StoreFunc storeFunc, List<? super MemorySegment> buffers) {
37 Deque<Object> stack = new ArrayDeque<>();
38 stack.push(arg);
39 for (Binding b : bindings) {
40 switch (b.tag()) {
41 case MOVE -> {
42 Binding.Move binding = (Binding.Move) b;
43 storeFunc.store(binding.storage(), binding.type(), stack.pop());
44 }
45 case DEREFERENCE -> {
46 Binding.Dereference deref = (Binding.Dereference) b;
47 MemorySegment operand = (MemorySegment) stack.pop();
48 MemoryAddress baseAddress = operand.baseAddress();
49 MemoryAddress readAddress = baseAddress.addOffset(deref.offset());
50 stack.push(SharedUtils.read(readAddress, deref.type()));
51 }
52 case COPY_BUFFER -> {
53 Binding.Copy binding = (Binding.Copy) b;
54 MemorySegment operand = (MemorySegment) stack.pop();
55 assert operand.byteSize() == binding.size() : "operand size mismatch";
56 MemorySegment copy = MemorySegment.allocateNative(binding.size(), binding.alignment());
57 copy.copyFrom(operand.asSlice(0, binding.size()));
58 buffers.add(copy);
59 stack.push(copy);
60 }
61 case ALLOC_BUFFER ->
62 throw new UnsupportedOperationException();
63 case CONVERT_ADDRESS ->
64 stack.push(((MemoryAddress) stack.pop()).toRawLongValue());
65 case BASE_ADDRESS ->
66 stack.push(((MemorySegment) stack.pop()).baseAddress());
67 case DUP ->
68 stack.push(stack.peekLast());
69 default -> throw new IllegalArgumentException("Unsupported tag: " + b);
70 }
71 }
72 }
73
74 static Object box(List<Binding> bindings, LoadFunc loadFunc) {
75 Deque<Object> stack = new ArrayDeque<>();
76 for (Binding b : bindings) {
77 switch (b.tag()) {
78 case MOVE -> {
79 Binding.Move binding = (Binding.Move) b;
80 stack.push(loadFunc.load(binding.storage(), binding.type()));
81 }
82 case DEREFERENCE -> {
83 Binding.Dereference binding = (Binding.Dereference) b;
84 Object value = stack.pop();
85 MemorySegment operand = (MemorySegment) stack.pop();
86 MemoryAddress baseAddress = operand.baseAddress();
87 MemoryAddress writeAddress = baseAddress.addOffset(binding.offset());
88 SharedUtils.write(writeAddress, binding.type(), value);
89 }
90 case COPY_BUFFER -> {
91 Binding.Copy binding = (Binding.Copy) b;
92 MemoryAddress operand = (MemoryAddress) stack.pop();
93 operand = MemoryAddressImpl.ofLongUnchecked(operand.toRawLongValue(), binding.size());
94 MemorySegment copy = MemorySegment.allocateNative(binding.size(), binding.alignment());
95 copy.copyFrom(operand.segment().asSlice(0, binding.size()));
96 stack.push(copy); // leaked
97 }
98 case ALLOC_BUFFER -> {
99 Binding.Allocate binding = (Binding.Allocate) b;
100 stack.push(MemorySegment.allocateNative(binding.size(), binding.alignment()));
101 }
102 case CONVERT_ADDRESS ->
103 stack.push(MemoryAddress.ofLong((long) stack.pop()));
104 case BASE_ADDRESS ->
105 stack.push(((MemorySegment) stack.pop()).baseAddress());
106 case DUP ->
107 stack.push(stack.peekLast());
108 default -> throw new IllegalArgumentException("Unsupported tag: " + b);
109 }
110 }
111
112 return stack.pop();
113 }
114
115 interface StoreFunc {
116 void store(VMStorage storage, Class<?> type, Object o);
117 }
118
119 interface LoadFunc {
120 Object load(VMStorage storage, Class<?> type);
121 }
122 }
|
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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.internal.foreign.abi;
24
25 import jdk.incubator.foreign.NativeScope;
26
27 import java.util.ArrayDeque;
28 import java.util.Deque;
29 import java.util.List;
30
31 public class BindingInterpreter {
32
33 static void unbox(Object arg, List<Binding> bindings, StoreFunc storeFunc, NativeScope scope) {
34 Deque<Object> stack = new ArrayDeque<>();
35 stack.push(arg);
36 for (Binding b : bindings) {
37 b.unbox(stack, storeFunc, scope);
38 }
39 }
40
41 static Object box(List<Binding> bindings, LoadFunc loadFunc) {
42 Deque<Object> stack = new ArrayDeque<>();
43 for (Binding b : bindings) {
44 b.box(stack, loadFunc);
45 }
46 return stack.pop();
47 }
48
49 interface StoreFunc {
50 void store(VMStorage storage, Class<?> type, Object o);
51 }
52
53 interface LoadFunc {
54 Object load(VMStorage storage, Class<?> type);
55 }
56 }
|