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