foreach $func (@list) {
$seen{"func:$func->{name}"} ++;
}
+ } elsif ($inc->{mode} eq 'call') {
+ my @list = grep { $_->{type} eq $inc->{mode} && $_->{name} =~ m/$inc->{regex}/ } values %data;
+
+ foreach $func (@list) {
+ $seen{"call:$func->{name}"} ++;
+ }
}
}
}
} elsif ($o =~ m/^access=([rwi]+)$/) {
$obj->{access} = $1;
} elsif ($o =~ m/^success=(.*)$/) {
- # for functions
+ # for functions?
$obj->{success} = $1;
} elsif ($o =~ m@^(rename|field:rename|func:rename)=(.*)@) {
my $target = $1;
my $defmode = $obj->{type} eq 'library' ? 'func' : 'field';
foreach $inc (@{$obj->{items}}) {
- if ($inc->{match} =~ m@^(field|func|define|struct|enum):/(.*)/$@) {
+ if ($inc->{match} =~ m@^(field|func|define|struct|enum|call):/(.*)/$@) {
$inc->{regex} = qr/$2/;
$inc->{mode} = $1; # ?? "$1-include";
- } elsif ($inc->{match} =~ m@^(field|func|define|struct|enum):(.*)$@) {
+ } elsif ($inc->{match} =~ m@^(field|func|define|struct|enum|call):(.*)$@) {
$inc->{regex} = qr/^$2$/;
$inc->{mode} = $1;
} elsif ($inc->{match} =~ m@^/(.*)/$@) {
}
sub formatFunctionDescriptor {
- my $c = shift @_;
+ my $c = shift;
my @arguments = @{$c->{arguments}};
my $result = $c->{result};
my $desc;
my $r = $c->{result_code};
$desc .= "$r->{typeInfo}->{type} $r->{name}\$value;\n";
}
+ $desc .= "$result->{typeInfo}->{carrier} res\$value;\n" if ($rtype ne "void");
$desc .= " try ";
$desc .= "(Frame frame = Memory.createFrame()) " if ($c->{resolveFrame});
$desc .= " $r->{typeInfo}->{declare};\n";
}
- $desc .= " $result->{typeInfo}->{carrier} res\$value = ($result->{typeInfo}->{carrier})" if ($rtype ne "void");
+ $desc .= " res\$value = ($result->{typeInfo}->{carrier})" if ($rtype ne "void");
$desc .= " " if ($rtype eq "void");
$index = 0;
}
$desc .= ");\n";
+ my $error_value;
+
if ($rtype ne "void") {
my $create = $result->{typeInfo}->{create};
$create =~ s/\$\{scope\}/scope()/;
}
+ my $success;
+
if ($c->{result_code}) {
my $r = $c->{result_code};
- my $success = $c->{success} ? $c->{success} : '0';
- $desc .= " $r->{name}\$value = $r->{name}.get(0);\n";
+ $error_value = "$r->{name}\$value";
+ $desc .= " $error_value = $r->{name}.get(0);\n";
+ $success = $c->{success} ? $c->{success} : '0';
+ } elsif ($c->{success}) {
+ $success = $c->{success};
+ $error_value = "res\$value";
+ } elsif ($inc->{success}) {
+ $success = $inc->{success};
+ $error_value = "res\$value";
+ }
+ if ($success) {
$desc .= " if (";
$count = 0;
foreach $s (split /,/,$success) {
$desc .= " || " if ($count++ > 0);
- $desc .= "($r->{name}\$value == $s)";
+ $desc .= "($error_value == $s)";
}
$desc .= ")\n";
}
$desc .= " } catch (Throwable t) { throw new RuntimeException(t); }\n";
# assume it's an int
- if ($c->{result_code}) {
- my $r = $c->{result_code};
- $desc .= " throw new RuntimeException(String.format(\"error=%d\", $r->{name}\$value));\n";
+ if ($error_value) {
+ $desc .= " throw new RuntimeException(String.format(\"error=%d\", $error_value));\n";
}
$desc .="}";
# TODO: parameterise and use typeInfo data.
if (!$isHandle) {
- print $f " MemorySegment segment;\n";
+ print $f " public final MemorySegment segment;\n";
# constructors
print $f " private $s->{name}(MemorySegment segment) { this.segment = segment; }\n";
print $f " public static $s->{name} create(MemorySegment segment) { return new $s->{name}(segment); }\n";
}
}
+# find flag
+sub flag {
+ my $obj = shift;
+ my $flag = shift;
+
+ return grep { $_ eq $flag } @{$obj->{options}};
+}
+
+# find option(s)
+sub option {
+ my $obj = shift;
+ my $name = shift;
+ my $rx = qr/^$name=/;
+
+ return grep { $_ =~ m/$rx/ } @{$obj->{options}};
+}
+
# Dump library type
foreach $lib ( @{$api->{library}} ) {
my $path = nameToPath($output, "$package.$lib->{name}");
+ my $dynamic = flag($lib, 'dynamic');
open (my $f, ">", $path) || die ("Cannot open '$path' for writing");
print $f "import java.lang.invoke.*;\n";
print $f "public class $lib->{name} {\n";
-
print $f " static ResourceScope scope() { return ResourceScope.globalScope(); }\n";
- # scan for matches
foreach $inc (@{$lib->{items}}) {
if ($inc->{mode} eq 'func') {
my @list = grep { $_->{type} eq $inc->{mode} && $_->{name} =~ m/$inc->{regex}/ } values %data;
ResourceScope scope();
}
+ public interface Array<T> {
+ long length();
+ T getAtIndex(long i);
+ }
+
public record FunctionPointer<T>(NativeSymbol symbol, T function) {
}
return v != null ? v.symbol().address() : MemoryAddress.NULL;
}
- public static long size(List<?> list) {
+ public static long length(List<?> list) {
return list != null ? list.size() : 0;
}
+ public static long length(Array<?> list) {
+ return list != null ? list.length() : 0;
+ }
+
+ public static long size(MemorySegment s) {
+ return s != null ? s.byteSize() : 0;
+ }
+
// hmm do i want this or not?
// -> added 'type safety'
// -> load of crap to be written
return create(MemorySegment.ofAddress(address, length, scope));
}
+ public static ByteArray createArray(MemoryAddress address, ResourceScope scope) {
+ return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
+ }
+
public static ByteArray createArray(long length, SegmentAllocator alloc) {
return create(alloc.allocateArray(Memory.BYTE, length));
}
}
public static ShortArray createArray(MemoryAddress address, long length, ResourceScope scope) {
- return create(MemorySegment.ofAddress(address, length, scope));
+ return create(MemorySegment.ofAddress(address, length * Memory.SHORT.byteSize(), scope));
+ }
+
+ public static ShortArray createArray(MemoryAddress address, ResourceScope scope) {
+ return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
}
public static ShortArray createArray(long length, SegmentAllocator alloc) {
}
public static IntArray createArray(MemoryAddress address, long length, ResourceScope scope) {
- return create(MemorySegment.ofAddress(address, length, scope));
+ return create(MemorySegment.ofAddress(address, length * Memory.INT.byteSize(), scope));
+ }
+
+ public static IntArray createArray(MemoryAddress address, ResourceScope scope) {
+ return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
}
public static IntArray createArray(long length, SegmentAllocator alloc) {
}
public static LongArray createArray(MemoryAddress address, long length, ResourceScope scope) {
- return create(MemorySegment.ofAddress(address, length, scope));
+ return create(MemorySegment.ofAddress(address, length * Memory.LONG.byteSize(), scope));
}
public static LongArray createArray(long length, SegmentAllocator alloc) {
}
public static FloatArray createArray(MemoryAddress address, long length, ResourceScope scope) {
- return create(MemorySegment.ofAddress(address, length, scope));
+ return create(MemorySegment.ofAddress(address, length * FLOAT.byteSize(), scope));
+ }
+
+ public static FloatArray createArray(MemoryAddress address, ResourceScope scope) {
+ return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
}
public static FloatArray createArray(long length, SegmentAllocator alloc) {
}
public static DoubleArray createArray(MemoryAddress address, long length, ResourceScope scope) {
- return create(MemorySegment.ofAddress(address, length, scope));
+ return create(MemorySegment.ofAddress(address, length * Memory.DOUBLE.byteSize(), scope));
+ }
+
+ public static DoubleArray createArray(MemoryAddress address, ResourceScope scope) {
+ return create(MemorySegment.ofAddress(address, Long.MAX_VALUE, scope));
}
public static DoubleArray createArray(long length, SegmentAllocator alloc) {
// This needs a separate scope from the array itself
public static class HandleArray<T extends Memory.Addressable> extends AbstractList<T> implements Memory.Addressable {
- final MemorySegment segment;
+ public final MemorySegment segment;
final ResourceScope scope;
BiFunction<MemoryAddress,ResourceScope,T> create;
struct /^_cl/ access= rename=s/^_cl/cl/ {
}
+
+# idea: dynamic will have a constructor that takes a SymbolLookup
+# and ResourceScope
+#library CLExt dynamic {
+# clIcdGetPlatformIDsKHR
+#}
+
library CL {
define:CLConstants
+ # core functions, resolved by dlopen
clGetPlatformIDs
clGetPlatformInfo
clGetDeviceIDs
clCreateCommandQueue
clCreateSampler
clEnqueueTask
-
}
+
# base constants
define CLConstants opencl.h {
/.*/cl.h/ file-include
}
+define CLPlatformConstants opencl.h {
+ /^CL_API_/ exclude
+ CL_PROGRAM_STRING_DEBUG_INFO exclude
+ /^__CL_/ exclude
+ # huge/nan/infinity in c aren't compatible with java's string representation
+ CL_HUGE_VALF|CL_HUGE_VAL|CL_NAN|CL_INFINITY exclude
+ /.*/cl_platform.h/ file-include
+
+}
+
func clGetPlatformIDs {
- num_entries implied=Memory.size(platforms)
+ num_entries implied=Memory.length(platforms)
}
func clGetDeviceIDs {
- num_entries implied=Memory.size(devices)
+ num_entries implied=Memory.length(devices)
}
func clCreateContext {
- num_devices implied=Memory.size(devices)
+ num_devices implied=Memory.length(devices)
errcode_ret result_code success=CL_SUCCESS
}