Small fixes
authorNot Zed <notzed@gmail.com>
Mon, 31 Jan 2022 20:07:06 +0000 (06:37 +1030)
committerNot Zed <notzed@gmail.com>
Mon, 31 Jan 2022 20:08:52 +0000 (06:38 +1030)
src/generate-native
src/template/Memory.java
test-opencl-basic/opencl.api

index d8d2497..b17434c 100755 (executable)
@@ -184,6 +184,12 @@ sub findRoots {
                                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}"} ++;
+                               }
                        }
                }
        }
@@ -313,7 +319,7 @@ sub analyseAPI {
                        } 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;
@@ -336,10 +342,10 @@ sub analyseAPI {
                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@^/(.*)/$@) {
@@ -547,7 +553,7 @@ sub formatTypeLayout {
 }
 
 sub formatFunctionDescriptor {
-       my $c = shift @_;
+       my $c = shift;
        my @arguments = @{$c->{arguments}};
        my $result = $c->{result};
        my $desc;
@@ -862,6 +868,7 @@ sub formatFunction {
                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});
@@ -872,7 +879,7 @@ sub formatFunction {
                $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;
@@ -896,6 +903,8 @@ sub formatFunction {
        }
        $desc .= ");\n";
 
+       my $error_value;
+
        if ($rtype ne "void") {
                my $create = $result->{typeInfo}->{create};
 
@@ -908,16 +917,27 @@ sub formatFunction {
                        $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";
                }
@@ -928,9 +948,8 @@ sub formatFunction {
        $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 .="}";
@@ -1278,7 +1297,7 @@ sub exportStruct {
 
        # 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";
@@ -1514,9 +1533,27 @@ foreach $obj ( @{$api->{struct}} ) {
        }
 }
 
+# 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");
 
@@ -1525,10 +1562,8 @@ foreach $lib ( @{$api->{library}} ) {
        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;
index 89b4c6c..b720f99 100644 (file)
@@ -157,6 +157,11 @@ public class Memory {
                ResourceScope scope();
        }
 
+       public interface Array<T> {
+               long length();
+               T getAtIndex(long i);
+       }
+
        public record FunctionPointer<T>(NativeSymbol symbol, T function) {
        }
 
@@ -172,10 +177,18 @@ public class Memory {
                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
@@ -194,6 +207,10 @@ public class Memory {
                        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));
                }
@@ -256,7 +273,11 @@ public class Memory {
                }
 
                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) {
@@ -317,7 +338,11 @@ public class Memory {
                }
 
                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) {
@@ -378,7 +403,7 @@ public class Memory {
                }
 
                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) {
@@ -439,7 +464,11 @@ public class Memory {
                }
 
                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) {
@@ -500,7 +529,11 @@ public class Memory {
                }
 
                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) {
@@ -612,7 +645,7 @@ public class Memory {
 
        // 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;
 
index 3728ba6..eeb8308 100644 (file)
@@ -5,9 +5,17 @@ struct cl_image_format access=rwi {
 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
@@ -116,24 +124,34 @@ library CL {
        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
 }