1 /* 2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 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 24 /* 25 * @test 26 * @modules java.base/jdk.internal.misc 27 * @run main/othervm StructUpcall 28 */ 29 30 import java.lang.invoke.MethodHandles; 31 import java.nicl.Libraries; 32 import java.nicl.NativeTypes; 33 import java.nicl.Scope; 34 import java.nicl.metadata.NativeCallback; 35 import java.nicl.metadata.NativeHeader; 36 import java.nicl.metadata.NativeLocation; 37 import java.nicl.metadata.NativeStruct; 38 import java.nicl.metadata.NativeType; 39 import java.nicl.metadata.Offset; 40 import java.nicl.types.LayoutType; 41 import java.nicl.types.Pointer; 42 import java.nicl.types.Struct; 43 44 public class StructUpcall { 45 private static final boolean DEBUG = false; 46 47 @NativeHeader 48 public static interface Index { 49 @NativeLocation(file="dummy", line=47, column=11, USR="C:@S@MyStruct") 50 @NativeStruct("[iiippp]") 51 static interface MyStruct extends Struct<MyStruct> { 52 @Offset(offset=0l) 53 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@field1") 54 @NativeType(layout="i", ctype="enum MyStructField1") 55 int field1$get(); 56 void field1$set(int i); 57 58 @Offset(offset=32l) 59 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@field2") 60 @NativeType(layout="i", ctype="int") 61 int field2$get(); 62 void field2$set(int i); 63 64 @Offset(offset=64l) 65 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@field3") 66 @NativeType(layout="i", ctype="int") 67 int field3$get(); 68 void field3$set(int i); 69 70 @Offset(offset=128l) 71 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@field4") 72 @NativeType(layout="p", ctype="const void *") 73 Pointer<Void> field4$get(); 74 void field4$set(Pointer<?> p); 75 76 @Offset(offset=192l) 77 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@field5") 78 @NativeType(layout="p", ctype="const void *") 79 Pointer<Void> field5$get(); 80 void field5$set(Pointer<?> p); 81 82 @Offset(offset=256l) 83 @NativeLocation(file="dummy", line=47, column=11, USR="c:@SA@MyStruct@FI@field6") 84 @NativeType(layout="p", ctype="const void *") 85 Pointer<Void> field6$get(); 86 void field6$set(Pointer<?> p); 87 } 88 89 @NativeCallback("([iiippp])V") 90 @FunctionalInterface 91 static interface MyStructVisitor { 92 @NativeLocation(file="dummy", line=47, column=11, USR="c:@F@slowsort") 93 public void fn(MyStruct s); 94 } 95 96 @NativeLocation(file="dummy", line=47, column=11, USR="c:@F@struct_upcall") 97 @NativeType(layout="(p:([iiip:Vp:Vp:V])V[iiip:Vp:Vp:V])V", ctype="void (struct_upcall_cb, struct MyStruct)", name="struct_upcall") 98 public abstract void struct_upcall(MyStructVisitor v, MyStruct s); 99 } 100 101 102 public static class MyStructVisitorImpl implements Index.MyStructVisitor { 103 MyStructVisitorImpl() { 104 } 105 106 @Override 107 public void fn(Index.MyStruct s) { 108 if (DEBUG) { 109 System.err.println("visit(" + s + ")"); 110 System.err.println("\ts.field1 = " + s.field1$get()); 111 System.err.println("\ts.field2 = " + s.field2$get()); 112 System.err.println("\ts.field3 = " + s.field3$get()); 113 System.err.println("\ts.field4 = " + s.field4$get().cast(NativeTypes.INT8).get()); 114 System.err.println("\ts.field5 = " + s.field5$get().cast(NativeTypes.INT8).get()); 115 System.err.println("\ts.field6 = " + s.field6$get().cast(NativeTypes.INT8).get()); 116 } 117 118 assertEquals(47, s.field1$get()); 119 assertEquals(11, s.field2$get()); 120 assertEquals(93, s.field3$get()); 121 assertEquals(123, s.field4$get().cast(NativeTypes.UINT8).get()); 122 assertEquals(124, s.field5$get().cast(NativeTypes.UINT8).get()); 123 assertEquals(125, s.field6$get().cast(NativeTypes.UINT8).get()); 124 } 125 } 126 127 public void test() { 128 Index i = Libraries.bind(Index.class, Libraries.loadLibrary(MethodHandles.lookup(), "Upcall")); 129 130 try (Scope scope = Scope.newNativeScope()) { 131 Index.MyStruct s = scope.allocateStruct(Index.MyStruct.class); 132 133 Pointer<Byte> p1 = scope.allocate(NativeTypes.INT8); 134 Pointer<Byte> p2 = scope.allocate(NativeTypes.INT8); 135 Pointer<Byte> p3 = scope.allocate(NativeTypes.INT8); 136 137 p1.set((byte)123); 138 p2.set((byte)124); 139 p3.set((byte)125); 140 141 s.field1$set(47); 142 s.field2$set(11); 143 s.field3$set(93); 144 s.field4$set(p1.cast(NativeTypes.VOID)); 145 s.field5$set(p2.cast(NativeTypes.VOID)); 146 s.field6$set(p3.cast(NativeTypes.VOID)); 147 148 assertEquals(47, s.field1$get()); 149 assertEquals(11, s.field2$get()); 150 assertEquals(93, s.field3$get()); 151 assertEquals(123, s.field4$get().cast(NativeTypes.INT8).get()); 152 assertEquals(124, s.field5$get().cast(NativeTypes.INT8).get()); 153 assertEquals(125, s.field6$get().cast(NativeTypes.INT8).get()); 154 155 Index.MyStructVisitor v = new MyStructVisitorImpl(); 156 157 i.struct_upcall(v, s); 158 } 159 160 if (DEBUG) { 161 System.err.println("back in test()\n"); 162 } 163 } 164 165 static void assertEquals(long expected, long actual) { 166 if (expected != actual) { 167 throw new RuntimeException("expected: " + expected + " does not match actual: " + actual); 168 } 169 } 170 171 public static void main(String[] args) { 172 new StructUpcall().test(); 173 } 174 }