< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/BindingInterpreter.java

Print this page

  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.MemoryHandles;
 27 import jdk.incubator.foreign.MemorySegment;
 28 import jdk.internal.foreign.MemoryAddressImpl;
 29 import jdk.internal.foreign.Utils;
 30 
 31 import java.lang.invoke.VarHandle;
 32 import java.nio.ByteOrder;
 33 import java.util.ArrayDeque;
 34 import java.util.Deque;
 35 import java.util.List;
 36 import java.util.function.Function;
 37 
 38 public class BindingInterpreter {
 39     private static final VarHandle VH_BYTE = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder());
 40     private static final VarHandle VH_CHAR = MemoryHandles.varHandle(char.class, ByteOrder.nativeOrder());
 41     private static final VarHandle VH_SHORT = MemoryHandles.varHandle(short.class, ByteOrder.nativeOrder());
 42     private static final VarHandle VH_INT = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
 43     private static final VarHandle VH_LONG = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
 44     private static final VarHandle VH_FLOAT = MemoryHandles.varHandle(float.class, ByteOrder.nativeOrder());
 45     private static final VarHandle VH_DOUBLE = MemoryHandles.varHandle(double.class, ByteOrder.nativeOrder());
 46 
 47     static void unbox(Object arg, List<Binding> bindings, Function<VMStorage,
 48             MemoryAddress> ptrFunction, List<? super MemorySegment> buffers) {
 49         Deque<Object> stack = new ArrayDeque<>();
 50         stack.push(arg);
 51         for (Binding b : bindings) {
 52             switch (b.tag()) {
 53                 case MOVE -> {
 54                     Binding.Move binding = (Binding.Move) b;
 55                     MemoryAddress ptr = ptrFunction.apply(binding.storage());
 56                     writeOverSized(ptr, binding.type(), stack.pop());
 57                 }
 58                 case DEREFERENCE -> {
 59                     Binding.Dereference deref = (Binding.Dereference) b;
 60                     MemorySegment operand = (MemorySegment) stack.pop();
 61                     MemoryAddress baseAddress = operand.baseAddress();
 62                     MemoryAddress readAddress = baseAddress.addOffset(deref.offset());
 63                     stack.push(read(readAddress, deref.type()));
 64                 }
 65                 case COPY_BUFFER -> {
 66                     Binding.Copy binding = (Binding.Copy) b;
 67                     MemorySegment operand = (MemorySegment) stack.pop();
 68                     assert operand.byteSize() == binding.size() : "operand size mismatch";
 69                     MemorySegment copy = MemorySegment.allocateNative(binding.size(), binding.alignment());
 70                     copy.copyFrom(operand.asSlice(0, binding.size()));
 71                     buffers.add(copy);
 72                     stack.push(copy);
 73                 }
 74                 case ALLOC_BUFFER ->
 75                     throw new UnsupportedOperationException();
 76                 case CONVERT_ADDRESS ->
 77                     stack.push(((MemoryAddress) stack.pop()).toRawLongValue());
 78                 case BASE_ADDRESS ->
 79                     stack.push(((MemorySegment) stack.pop()).baseAddress());
 80                 case DUP ->
 81                     stack.push(stack.peekLast());
 82                 default -> throw new IllegalArgumentException("Unsupported tag: " + b);
 83             }
 84         }
 85     }
 86 
 87     static Object box(List<Binding> bindings, Function<VMStorage, MemoryAddress> ptrFunction) {
 88         Deque<Object> stack = new ArrayDeque<>();
 89         for (Binding b : bindings) {
 90             switch (b.tag()) {
 91                 case MOVE -> {
 92                     Binding.Move binding = (Binding.Move) b;
 93                     MemoryAddress ptr = ptrFunction.apply(binding.storage());
 94                     stack.push(read(ptr, binding.type()));
 95                 }
 96                 case DEREFERENCE -> {
 97                     Binding.Dereference binding = (Binding.Dereference) b;
 98                     Object value = stack.pop();
 99                     MemorySegment operand = (MemorySegment) stack.pop();
100                     MemoryAddress baseAddress = operand.baseAddress();
101                     MemoryAddress writeAddress = baseAddress.addOffset(binding.offset());
102                     write(writeAddress, binding.type(), value);
103                 }
104                 case COPY_BUFFER -> {
105                     Binding.Copy binding = (Binding.Copy) b;
106                     MemoryAddress operand = (MemoryAddress) stack.pop();
107                     operand = MemoryAddressImpl.ofLongUnchecked(operand.toRawLongValue(), binding.size());
108                     MemorySegment copy = MemorySegment.allocateNative(binding.size(), binding.alignment());
109                     copy.copyFrom(operand.segment().asSlice(0, binding.size()));
110                     stack.push(copy); // leaked
111                 }
112                 case ALLOC_BUFFER -> {
113                     Binding.Allocate binding = (Binding.Allocate) b;
114                     stack.push(MemorySegment.allocateNative(binding.size(), binding.alignment()));
115                 }
116                 case CONVERT_ADDRESS ->
117                     stack.push(MemoryAddress.ofLong((long) stack.pop()));
118                 case BASE_ADDRESS ->
119                     stack.push(((MemorySegment) stack.pop()).baseAddress());
120                 case DUP ->
121                     stack.push(stack.peekLast());
122                 default -> throw new IllegalArgumentException("Unsupported tag: " + b);
123             }
124         }
125 
126        return stack.pop();
127     }
128 
129     private static void writeOverSized(MemoryAddress ptr, Class<?> type, Object o) {
130         // use VH_LONG for integers to zero out the whole register in the process
131         if (type == long.class) {
132             VH_LONG.set(ptr, (long) o);
133         } else if (type == int.class) {
134             VH_LONG.set(ptr, (long) (int) o);
135         } else if (type == short.class) {
136             VH_LONG.set(ptr, (long) (short) o);
137         } else if (type == char.class) {
138             VH_LONG.set(ptr, (long) (char) o);
139         } else if (type == byte.class) {
140             VH_LONG.set(ptr, (long) (byte) o);
141         } else if (type == float.class) {
142             VH_FLOAT.set(ptr, (float) o);
143         } else if (type == double.class) {
144             VH_DOUBLE.set(ptr, (double) o);
145         } else {
146             throw new IllegalArgumentException("Unsupported carrier: " + type);
147         }
148     }
149 
150     private static void write(MemoryAddress ptr, Class<?> type, Object o) {
151         if (type == long.class) {
152             VH_LONG.set(ptr, (long) o);
153         } else if (type == int.class) {
154             VH_INT.set(ptr, (int) o);
155         } else if (type == short.class) {
156             VH_SHORT.set(ptr, (short) o);
157         } else if (type == char.class) {
158             VH_CHAR.set(ptr, (char) o);
159         } else if (type == byte.class) {
160             VH_BYTE.set(ptr, (byte) o);
161         } else if (type == float.class) {
162             VH_FLOAT.set(ptr, (float) o);
163         } else if (type == double.class) {
164             VH_DOUBLE.set(ptr, (double) o);
165         } else {
166             throw new IllegalArgumentException("Unsupported carrier: " + type);
167         }
168     }
169 
170     private static Object read(MemoryAddress ptr, Class<?> type) {
171         if (type == long.class) {
172             return (long) VH_LONG.get(ptr);
173         } else if (type == int.class) {
174             return (int) VH_INT.get(ptr);
175         } else if (type == short.class) {
176             return (short) VH_SHORT.get(ptr);
177         } else if (type == char.class) {
178             return (char) VH_CHAR.get(ptr);
179         } else if (type == byte.class) {
180             return (byte) VH_BYTE.get(ptr);
181         } else if (type == float.class) {
182             return (float) VH_FLOAT.get(ptr);
183         } else if (type == double.class) {
184             return (double) VH_DOUBLE.get(ptr);
185         } else {
186             throw new IllegalArgumentException("Unsupported carrier: " + type);
187         }
188     }
189 }

  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 }
< prev index next >