1 # -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*-
4 # 'invoke' is a simple string template
5 # variables are defined by method.pm
7 # normal function invocation
9 static final MethodHandle {name}$FH = Memory.downcall("{name}", {function-descriptor});
10 public {static}{java-result} {rename}({java-arguments}) {
11 {native-output-define}
12 {native-result-define}
15 {native-result-assign}{name}$FH.invokeExact({native-call});
22 } catch (Throwable t) {
23 throw new RuntimeException(t);
29 invoke-dynamic-init {{
30 {name}$FH = Memory.downcall("{name}", {function-descriptor}, resolve, scope);
34 final MethodHandle {name}$FH;
35 public {java-result} {rename}({java-arguments}) {
36 {native-output-define}
37 {native-result-define}
40 {native-result-assign}{name}$FH.invokeExact({native-call});
47 } catch (Throwable t) {
48 throw new RuntimeException(t);
54 # callback function/types
56 public static FunctionPointer<{rename}> downcall(MemoryAddress addr$, ResourceScope scope$) {
57 NativeSymbol symbol$ = NativeSymbol.ofAddress("{rename}", addr$, scope$);
58 MethodHandle {rename}$FH = Memory.downcall(symbol$, descriptor());
59 return new FunctionPointer<{rename}>(
61 ({java-arguments}) -> {
62 {native-output-define}
63 {native-result-define}
66 {native-result-assign}{rename}$FH.invokeExact({native-call});
73 } catch (Throwable t) {
74 throw new RuntimeException(t);
81 public static FunctionPointer<{rename}> upcall({rename} target$, ResourceScope scope$) {
82 interface Trampoline {
83 {java-result} call({native-arguments});
85 Trampoline trampoline = ({native-arguments}) -> {
87 try (ResourceScope upcallScope$ = ResourceScope.newConfinedScope()) {
88 {trampoline-result-define}target$.call({java-call});
89 {trampoline-result-return}
92 return new FunctionPointer<>(
94 MethodHandles.lookup(),
106 # structs - normal structs
107 # handle - anonymous structs
108 # library - library template
113 import jdk.incubator.foreign.*;
114 import java.lang.invoke.*;
115 import au.notzed.nativez.*;
117 public class {name} {
124 func:template=code:method=invoke-dynamic
125 init:template=code:method=invoke-dynamic-init {{
127 import jdk.incubator.foreign.*;
128 import java.lang.invoke.*;
129 import java.util.function.Function;
130 import au.notzed.nativez.*;
132 public class {name} {
133 {name}(Function<String,MemoryAddress> resolve, ResourceScope scope) {
136 public static {name} create(Function<String,MemoryAddress> resolve, ResourceScope scope) {
137 return new {name}(resolve, scope);
147 public interface {name} {
154 import jdk.incubator.foreign.*;
155 import jdk.incubator.foreign.MemoryLayout.*;
156 import java.lang.invoke.*;
157 import au.notzed.nativez.*;
159 public class {rename} implements Pointer {
161 public final MemorySegment segment;
163 private {rename}(MemorySegment segment) {
164 this.segment = segment;
168 public static {rename} create(MemorySegment segment) {
169 return new {rename}(segment);
172 public static {rename} create(MemoryAddress address, ResourceScope scope) {
173 return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope)) : null;
176 public static {rename} create(SegmentAllocator frame) {
177 return create(frame.allocate(LAYOUT));
181 public final MemoryAddress address() {
182 return segment.address();
186 public final ResourceScope scope() {
187 return segment.scope();
190 public final MemorySegment segment() {
204 import jdk.incubator.foreign.*;
205 import jdk.incubator.foreign.MemoryLayout.*;
206 import java.lang.invoke.*;
207 import au.notzed.nativez.*;
209 public class {rename} implements Pointer, Array<{rename}> {
211 public final MemorySegment segment;
213 private {rename}(MemorySegment segment) {
214 this.segment = segment;
218 public static {rename} create(MemorySegment segment) {
219 return new {rename}(segment);
222 public static {rename} create(MemoryAddress address, ResourceScope scope) {
223 return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, LAYOUT.byteSize(), scope)) : null;
226 public static {rename} create(SegmentAllocator frame) {
227 return create(frame.allocate(LAYOUT));
230 public static {rename} createArray(MemoryAddress address, ResourceScope scope) {
231 return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope)) : null;
234 public static {rename} createArray(MemoryAddress address, long length, ResourceScope scope) {
235 return MemoryAddress.NULL != address ? create(MemorySegment.ofAddress(address, LAYOUT.byteSize() * length, scope)) : null;
238 public static {rename} createArray(long length, SegmentAllocator alloc) {
239 return create(alloc.allocateArray(LAYOUT, length));
243 public final MemoryAddress address() {
244 return segment.address();
248 public final ResourceScope scope() {
249 return segment.scope();
252 public final MemorySegment segment() {
257 public long length() {
258 return segment.byteSize() / LAYOUT.byteSize();
262 public {rename} getAtIndex(long index) {
264 return {rename}.create((MemorySegment){name}$SH.invokeExact(segment, index));
265 } catch (Throwable t) {
266 throw new RuntimeException(t);
275 final static MethodHandle {name}$SH = MemoryLayout.sequenceLayout(LAYOUT).sliceHandle(PathElement.sequenceElement());
281 import jdk.incubator.foreign.*;
282 import java.lang.invoke.*;
283 import au.notzed.nativez.*;
285 public class {rename} implements Pointer {
287 MemoryAddress address;
290 private {rename}(MemoryAddress address, ResourceScope scope) {
291 this.address = address;
296 public static {rename} create(MemoryAddress address, ResourceScope scope) {
297 return MemoryAddress.NULL != address ? new {rename}(address, scope) : null;
300 public static HandleArray<{rename}> createArray(long count, SegmentAllocator alloc) {
301 return HandleArray.createArray(count, alloc, {rename}::create);
305 public MemoryAddress address() {
310 public ResourceScope scope() {
321 import jdk.incubator.foreign.*;
322 import java.lang.invoke.*;
323 import au.notzed.nativez.*;
326 public interface {rename} {
327 {java-result} call({java-arguments});
329 public static FunctionDescriptor descriptor() {
330 return {function-descriptor};
339 # do I want this to be perl code as template or just a template?
341 get set=value={getnative} {{
342 public {type} get{rename}() {
346 geti set=value={getnative} set=segment=segment {{
347 # TODO: final static VarHandle {name}$VI = MemoryLayout.sequenceLayout(LAYOUT).varHandle(PathElement.sequenceElement(), PathElement.groupElement("{name}"));
348 public {type} get{rename}AtIndex(long index) {
349 // option a: resolve an offset segment and asme as above with set=segment=segment
350 // option b: an indexed varhandle
351 MemorySegment segment = segment().asSlice(index * LAYOUT.byteSize(), LAYOUT.byteSize());
355 set set=value=value {{
356 public void set{rename}({type} value) {
360 seti set=value=value set=segment=segment {{
361 public void set{rename}AtIndex(long index, {type} value) {
362 MemorySegment segment = segment().asSlice(index * LAYOUT.byteSize(), LAYOUT.byteSize());
368 # set requires allocations, not sure if it should be Frame or Scope?
370 get set=value={getnative} {{
371 public {type} get{rename}() {
375 geti set=value={getnative} set=segment=segment {{
376 public {type} get{rename}AtIndex(long index) {
377 // option a: resolve an offset segment and asme as above with set=segment=segment
378 // option b: an indexed varhandle
379 MemorySegment segment = segment().asSlice(index * LAYOUT.byteSize(), LAYOUT.byteSize());
383 set set=value=value {{
384 public void set{rename}(Frame frame$, {type} value) {
388 seti set=value=value set=segment=segment {{
389 public void set{rename}AtIndex(Frame frame$, long index, {type} value) {
390 MemorySegment segment = segment().asSlice(index * LAYOUT.byteSize(), LAYOUT.byteSize());
398 public {typei} get{rename}Element(long i) {
402 set set=index=i set=value=value {{
403 public void set{rename}Element(long i, {typei} value) {
409 code getsetelement2d {
410 get set=index0=i set=index1=j {{
411 public {typei} get{rename}Element(long i, long j) {
415 set set=index0=i set=index1=j set=value=value {{
416 public void set{rename}Element(long i, long j, {typei} value) {
424 public {type} get{rename}() {
427 } catch (Throwable t) {
428 throw new RuntimeException(t);