1 /*
2 * Copyright (c) 2024, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package wrap;
26
27 import java.lang.foreign.AddressLayout;
28 import java.lang.foreign.Arena;
29 import java.lang.foreign.MemorySegment;
30 import java.lang.foreign.ValueLayout;
31
32 import static java.lang.foreign.ValueLayout.ADDRESS;
33 import static java.lang.foreign.ValueLayout.JAVA_BYTE;
34 import static java.lang.foreign.ValueLayout.JAVA_DOUBLE;
35 import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
36 import static java.lang.foreign.ValueLayout.JAVA_INT;
37 import static java.lang.foreign.ValueLayout.JAVA_LONG;
38 import static java.lang.foreign.ValueLayout.JAVA_SHORT;
39
40 public class Wrap {
41 public interface Ptr{
42 MemorySegment ptr();
43 long sizeof();
44 }
45 public interface Arr extends Ptr{
46 default long length(){
47 return sizeof()/elementSize();
48 }
49 long elementSize();
50 }
51 public record IntPtr(MemorySegment ptr) implements Ptr {
52 public static IntPtr of(Arena arena, int value) {
53 return new IntPtr(arena.allocateFrom(JAVA_INT, value));
54 }
55
56 public int set(int value) {
57 ptr.set(JAVA_INT, 0, value);
58 return value;
59 }
60
61 public int get() {
62 return ptr.get(JAVA_INT, 0);
63 }
64
65 @Override public long sizeof(){
66 return JAVA_INT.byteSize();
67 }
68 }
69
70 public record LongPtr(MemorySegment ptr) implements Ptr{
71 public static LongPtr of(Arena arena, long value) {
72 return new LongPtr(arena.allocateFrom(JAVA_LONG, value));
73 }
74
75 public long set(long value) {
76 ptr.set(JAVA_LONG, 0, value);
77 return value;
78 }
79
80 public long get() {
81 return ptr.get(JAVA_LONG, 0);
82 }
83
84 @Override
85 public long sizeof(){
86 return JAVA_LONG.byteSize();
87 }
88 }
89 public record DoublePtr(MemorySegment ptr) implements Ptr{
90 public static DoublePtr of(Arena arena, double value) {
91 return new DoublePtr(arena.allocateFrom(JAVA_DOUBLE, value));
92 }
93
94 public double set(double value) {
95 ptr.set(JAVA_DOUBLE, 0, value);
96 return value;
97 }
98
99 public double get() {
100 return ptr.get(JAVA_DOUBLE, 0);
101 }
102
103 @Override
104 public long sizeof(){
105 return JAVA_DOUBLE.byteSize();
106 }
107 }
108
109 public record PtrArr(MemorySegment ptr) implements Arr{
110 public static PtrArr of(Arena arena, int size) {
111 return new PtrArr(arena.allocate(ADDRESS, size));
112 }
113 public static PtrArr of(Arena arena, MemorySegment ...memorySegments) {
114 var ptrArray= new PtrArr(arena.allocate(ADDRESS, memorySegments.length));
115 for (int i = 0; i < memorySegments.length; i++) {
116 ptrArray.set(i, memorySegments[i]);
117 }
118 return ptrArray;
119 }
120
121 public static PtrArr of(Arena arena, Ptr ...ptrs) {
122 var ptrArray= new PtrArr(arena.allocate(ADDRESS, ptrs.length));
123 for (int i = 0; i < ptrs.length; i++) {
124 ptrArray.set(i, ptrs[i].ptr());
125 }
126 return ptrArray;
127 }
128 public static PtrArr of(Arena arena, String ...strings) {
129 var ptrArray= new PtrArr(arena.allocate(ADDRESS, strings.length));
130 for (int i = 0; i < strings.length; i++) {
131 ptrArray.set(i, CStrPtr.of(arena,strings[i]).ptr());
132 }
133 return ptrArray;
134 }
135
136
137 public MemorySegment set(int idx, MemorySegment value) {
138 ptr.set(AddressLayout.ADDRESS, idx* ADDRESS.byteSize(), value);
139 return value;
140 }
141
142 public MemorySegment get(int idx) {
143 return ptr.get(AddressLayout.ADDRESS, idx* ADDRESS.byteSize());
144 }
145
146 @Override
147 public long sizeof(){
148 return ptr.byteSize();
149 }
150 @Override public long elementSize(){
151 return AddressLayout.ADDRESS.byteSize();
152 }
153 }
154
155 public record CStrPtr(MemorySegment ptr, int len) implements Ptr{
156 public static CStrPtr of(Arena arena, int len) {
157 return new CStrPtr(arena.allocate(JAVA_BYTE, len), len);
158 }
159 public static CStrPtr of(Arena arena, String str) {
160 return new CStrPtr(arena.allocateFrom( str), str.length());
161 }
162 public static CStrPtr of( MemorySegment str) {
163 return new CStrPtr(str, (int)str.byteSize());
164 }
165
166 public String get() {
167 return ptr.getString(0);
168 }
169 @Override
170 public long sizeof(){
171 return JAVA_BYTE.byteSize();
172 }
173
174 @Override public String toString(){
175 return get();
176 }
177 }
178
179 public record FloatPtr(MemorySegment ptr) implements Ptr{
180 public static FloatPtr of(Arena arena, float value) {
181 return new FloatPtr(arena.allocateFrom(JAVA_FLOAT, value));
182 }
183
184 public float set(float value) {
185 ptr.set(JAVA_FLOAT, 0, value);
186 return value;
187 }
188
189 public float get() {
190 return ptr.get(JAVA_FLOAT, 0);
191 }
192
193 @Override
194 public long sizeof(){
195 return JAVA_FLOAT.byteSize();
196 }
197 }
198 public record ShortPtr(MemorySegment ptr) implements Ptr{
199 public static ShortPtr of(Arena arena, short value) {
200 return new ShortPtr(arena.allocateFrom(JAVA_SHORT, value));
201 }
202
203 public short set(short value) {
204 ptr.set(JAVA_SHORT, 0, value);
205 return value;
206 }
207
208 public short get() {
209 return ptr.get(JAVA_SHORT, 0);
210 }
211
212 @Override
213 public long sizeof(){
214 return JAVA_SHORT.byteSize();
215 }
216 }
217
218 public record FloatArr(MemorySegment ptr) implements Arr{
219 public static FloatArr of(Arena arena, int length) {
220 return new FloatArr(arena.allocate(JAVA_FLOAT, length));
221 }
222 public static FloatArr of(Arena arena, float[] floats) {
223 return new FloatArr(arena.allocateFrom(JAVA_FLOAT, floats));
224 }
225
226 public float set(int idx, float value) {
227 ptr.set(JAVA_FLOAT, idx*JAVA_FLOAT.byteSize(), value);
228 return value;
229 }
230
231 public float get(int idx) {
232 return ptr.get(JAVA_FLOAT, JAVA_FLOAT.byteSize()*idx);
233 }
234
235
236 @Override public long elementSize(){
237 return JAVA_FLOAT.byteSize();
238 }
239
240 @Override
241 public long sizeof(){
242 return ptr.byteSize();
243 }
244 }
245
246 public record IntArr(MemorySegment ptr) implements Arr{
247 public static IntArr of(Arena arena, int length) {
248 return new IntArr(arena.allocate(JAVA_INT, length));
249 }
250 public static IntArr ofValues(Arena arena, int ...values ) {
251 return of(arena, values);
252 }
253 public static IntArr of(Arena arena, int[] floats) {
254 return new IntArr(arena.allocateFrom(JAVA_INT, floats));
255 }
256
257 public int set(int idx, int value) {
258 ptr.set(JAVA_INT, idx*JAVA_INT.byteSize(), value);
259 return value;
260 }
261
262 public int get(int idx) {
263 return ptr.get(JAVA_INT, JAVA_INT.byteSize()*idx);
264 }
265
266 @Override public long elementSize(){
267 return JAVA_INT.byteSize();
268 }
269
270 @Override
271 public long sizeof(){
272 return ptr.byteSize();
273 }
274 }
275
276 public record Float4Arr(MemorySegment ptr) implements Arr{
277 public record float4(float x, float y, float z, float w ) {
278 public static float4 of(float x, float y, float z, float w) {
279 return new float4(x, y, z, w);
280 }
281 static public final float4 zero = new float4(0.f, 0.f, 0.f, 0.f);
282 public static float4 of() {
283 return zero;
284 }
285 public float4 sub(float4 rhs){
286 return of(x-rhs.x,y-rhs.y,z-rhs.z,w-rhs.w);
287 }
288 public float4 add(float4 rhs){
289 return of(x+rhs.x,y+rhs.y,z+rhs.z,w+rhs.w);
290 }
291
292 public float4 mul(float rhs) {
293 return of(x*rhs,y*rhs,z*rhs,w*rhs);
294 }
295 public float4 mul(float4 rhs) {
296 return of(x* rhs.x,y* rhs.y,z* rhs.z,w*rhs.w);
297 }
298 }
299
300
301 public static Float4Arr of(Arena arena, int length) {
302 return new Float4Arr(arena.allocate(JAVA_FLOAT, length*JAVA_FLOAT.byteSize()));
303 }
304 public static Float4Arr of(Arena arena, float[] floats) {
305 return new Float4Arr(arena.allocateFrom(JAVA_FLOAT, floats));
306 }
307
308 public float4 get(int idx){
309 return float4.of(
310 ptr.get(JAVA_FLOAT, elementSize()*idx),
311 ptr.get(JAVA_FLOAT, elementSize()*idx+JAVA_FLOAT.byteSize()),
312 ptr.get(JAVA_FLOAT, elementSize()*idx+JAVA_FLOAT.byteSize()*2),
313 ptr.get(JAVA_FLOAT, elementSize()*idx+JAVA_FLOAT.byteSize()*3));
314
315 }
316 public void set(int idx, float4 f4) {
317 ptr.set(JAVA_FLOAT, idx*elementSize(), f4.x());
318 ptr.set(JAVA_FLOAT, idx*elementSize()+JAVA_FLOAT.byteSize(), f4.y());
319 ptr.set(JAVA_FLOAT, idx*elementSize()+JAVA_FLOAT.byteSize()*2, f4.z());
320 ptr.set(JAVA_FLOAT, idx*elementSize()+JAVA_FLOAT.byteSize()*3, f4.w());
321 }
322 public float setx(int idx, float value) {
323 ptr.set(JAVA_FLOAT, idx*elementSize(), value);
324 return value;
325 }
326 public float sety(int idx, float value) {
327 ptr.set(JAVA_FLOAT, idx*elementSize()+JAVA_FLOAT.byteSize(), value);
328 return value;
329 }
330 public float setz(int idx, float value) {
331 ptr.set(JAVA_FLOAT, idx*elementSize()+JAVA_FLOAT.byteSize()*2, value);
332 return value;
333 }
334 public float setw(int idx, float value) {
335 ptr.set(JAVA_FLOAT, idx*elementSize()+JAVA_FLOAT.byteSize()*3, value);
336 return value;
337 }
338
339 public float getx(int idx) {
340 return ptr.get(JAVA_FLOAT, elementSize()*idx);
341 }
342 public float gety(int idx) {
343 return ptr.get(JAVA_FLOAT, elementSize()*idx+JAVA_FLOAT.byteSize());
344 }
345 public float getz(int idx) {
346 return ptr.get(JAVA_FLOAT, elementSize()*idx+JAVA_FLOAT.byteSize()*2);
347 }
348 public float getw(int idx) {
349 return ptr.get(JAVA_FLOAT, elementSize()*idx+JAVA_FLOAT.byteSize()*3);
350 }
351
352 @Override public long elementSize(){
353 return JAVA_FLOAT.byteSize()*4;
354 }
355
356 @Override
357 public long sizeof(){
358 return ptr.byteSize();
359 }
360 }
361
362 public static void dump(MemorySegment s, int bytes){
363 char[] chars = new char[16];
364 boolean end=false;
365 for (int i = 0; !end && i < bytes; i++) {
366 int signed = s.get(ValueLayout.JAVA_BYTE, i);
367 int unsigned = ((signed<0)?signed+256:signed)&0xff;
368 chars[i%16] = (char)unsigned;
369
370 System.out.printf("%02x ", unsigned);
371 if (unsigned == 0){
372 end=true;
373 }
374 if (i>0 && i%16==0){
375 System.out.print(" | ");
376 for (int c=0; c<16; c++){
377 if (chars[c]<32){
378 System.out.print(switch (chars[c]){
379 case '\0'->"\\0";
380 case '\n'->"\\n";
381 case '\r'->"\\r";
382 default -> chars[c]+"";
383 });
384
385 }else {
386 System.out.print(chars[c]);
387 }
388 }
389 System.out.println();
390 }
391 }
392 }
393 }