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