< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/Binding.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.MemoryLayout;
 26 
 27 import java.util.ArrayList;
 28 import java.util.List;
 29 import java.util.Objects;
 30 



 31 /**
 32  * The binding operators defined in the Binding class can be combined into argument and return value processing 'recipes'.
 33  *
 34  * The binding operators are interpreted using a stack-base interpreter. Operators can either consume operands from the
 35  * stack, or push them onto the stack.
 36  *
 37  * In the description of each binding we talk about 'boxing' and 'unboxing'.
 38  *  - Unboxing is the process of taking a Java value and decomposing it, and storing components into machine
 39  *    storage locations. As such, the binding interpreter stack starts with the Java value on it, and should end empty.
 40  *  - Boxing is the process of re-composing a Java value by pulling components from machine storage locations.
 41  *    If a MemorySegment is needed to store the result, one should be allocated using the ALLOCATE_BUFFER operator.
 42  *    The binding interpreter stack starts off empty, and ends with the value to be returned as the only value on it.
 43  * A binding operator can be interpreted differently based on whether we are boxing or unboxing a value. For example,
 44  * the CONVERT_ADDRESS operator 'unboxes' a MemoryAddress to a long, but 'boxes' a long to a MemoryAddress.
 45  *
 46  * Here are some examples of binding recipes derived from C declarations, and according to the Windows ABI (recipes are
 47  * ABI-specific). Note that each argument has it's own recipe, which is indicated by '[number]:' (though, the only
 48  * example that has multiple arguments is the one using varargs).
 49  *
 50  * --------------------

347      * The [type] must be one of byte, short, char, int, long, float, or double
348      */
349     public static class Dereference extends Binding {
350         private final long offset;
351         private final Class<?> type;
352 
353         private Dereference(long offset, Class<?> type) {
354             super(Tag.DEREFERENCE);
355             this.offset = offset;
356             this.type = type;
357         }
358 
359         public long offset() {
360             return offset;
361         }
362 
363         public Class<?> type() {
364             return type;
365         }
366 




367         @Override
368         public String toString() {
369             return "Dereference{" +
370                     "tag=" + tag() +
371                     ", offset=" + offset +
372                     ", type=" + type +
373                     '}';
374         }
375 
376         @Override
377         public boolean equals(Object o) {
378             if (this == o) return true;
379             if (o == null || getClass() != o.getClass()) return false;
380             Dereference that = (Dereference) o;
381             return offset == that.offset &&
382                     type.equals(that.type);
383         }
384 
385         @Override
386         public int hashCode() {

  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.MemoryHandles;
 26 import jdk.incubator.foreign.MemoryLayout;
 27 
 28 import java.util.ArrayList;
 29 import java.util.List;
 30 import java.util.Objects;
 31 
 32 import java.lang.invoke.VarHandle;
 33 import java.nio.ByteOrder;
 34 
 35 /**
 36  * The binding operators defined in the Binding class can be combined into argument and return value processing 'recipes'.
 37  *
 38  * The binding operators are interpreted using a stack-base interpreter. Operators can either consume operands from the
 39  * stack, or push them onto the stack.
 40  *
 41  * In the description of each binding we talk about 'boxing' and 'unboxing'.
 42  *  - Unboxing is the process of taking a Java value and decomposing it, and storing components into machine
 43  *    storage locations. As such, the binding interpreter stack starts with the Java value on it, and should end empty.
 44  *  - Boxing is the process of re-composing a Java value by pulling components from machine storage locations.
 45  *    If a MemorySegment is needed to store the result, one should be allocated using the ALLOCATE_BUFFER operator.
 46  *    The binding interpreter stack starts off empty, and ends with the value to be returned as the only value on it.
 47  * A binding operator can be interpreted differently based on whether we are boxing or unboxing a value. For example,
 48  * the CONVERT_ADDRESS operator 'unboxes' a MemoryAddress to a long, but 'boxes' a long to a MemoryAddress.
 49  *
 50  * Here are some examples of binding recipes derived from C declarations, and according to the Windows ABI (recipes are
 51  * ABI-specific). Note that each argument has it's own recipe, which is indicated by '[number]:' (though, the only
 52  * example that has multiple arguments is the one using varargs).
 53  *
 54  * --------------------

351      * The [type] must be one of byte, short, char, int, long, float, or double
352      */
353     public static class Dereference extends Binding {
354         private final long offset;
355         private final Class<?> type;
356 
357         private Dereference(long offset, Class<?> type) {
358             super(Tag.DEREFERENCE);
359             this.offset = offset;
360             this.type = type;
361         }
362 
363         public long offset() {
364             return offset;
365         }
366 
367         public Class<?> type() {
368             return type;
369         }
370 
371         public VarHandle varHandle() {
372             return MemoryHandles.withOffset(MemoryHandles.varHandle(type, ByteOrder.nativeOrder()), offset);
373         }
374 
375         @Override
376         public String toString() {
377             return "Dereference{" +
378                     "tag=" + tag() +
379                     ", offset=" + offset +
380                     ", type=" + type +
381                     '}';
382         }
383 
384         @Override
385         public boolean equals(Object o) {
386             if (this == o) return true;
387             if (o == null || getClass() != o.getClass()) return false;
388             Dereference that = (Dereference) o;
389             return offset == that.offset &&
390                     type.equals(that.type);
391         }
392 
393         @Override
394         public int hashCode() {
< prev index next >