Pass array type, not subty to primitive_arr_*_hu for more context
[ldk-java] / java_strings.py
index 9513db8ec8c9898c841206aca374a1ed8cabe4a4..6308ed518dd795e953f7ced3c3bdca265631fc75 100644 (file)
@@ -74,8 +74,7 @@ public class bindings {
                if (!get_lib_version_string().equals(version.get_ldk_java_bindings_version()))
                        throw new IllegalArgumentException("Compiled LDK library and LDK class failes do not match");
                // Fetching the LDK versions from C also checks that the header and binaries match
-               get_ldk_c_bindings_version();
-               get_ldk_version();
+               System.err.println("Loaded LDK-Java Bindings " + version.get_ldk_java_bindings_version() + " with LDK " + get_ldk_version() + " and LDK-C-Bindings " + get_ldk_c_bindings_version());
        }
        static native void init(java.lang.Class c, java.lang.Class slicedef);
        static native void init_class_cache();
@@ -151,6 +150,27 @@ class CommonBase {
        }
 }"""
 
+        self.scalar_defn = """public class BigEndianScalar extends CommonBase {
+       /** The bytes of the scalar value, in big endian */
+       public final byte[] scalar_bytes;
+
+       BigEndianScalar(java.lang.Object _dummy, long ptr) {
+               super(ptr);
+               this.scalar_bytes = bindings.BigEndianScalar_get_bytes(ptr);
+       }
+       public BigEndianScalar(byte[] scalar_bytes) {
+               super(bindings.BigEndianScalar_new(scalar_bytes));
+               this.scalar_bytes = bindings.BigEndianScalar_get_bytes(ptr);
+       }
+
+       @Override @SuppressWarnings(\"deprecation\")
+       protected void finalize() throws Throwable {
+               super.finalize();
+               if (ptr != 0) { bindings.BigEndianScalar_free(ptr); }
+       }
+}"""
+
+
         self.c_file_pfx = """#include <jni.h>
 // On OSX jlong (ie long long) is not equivalent to int64_t, so we override here
 #define int64_t jlong
@@ -216,7 +236,6 @@ void __attribute__((constructor)) debug_log_version() {
                DEBUG_PRINT("LDK version did not match the header we built against\\n");
        if (check_get_ldk_bindings_version() == NULL)
                DEBUG_PRINT("LDK C Bindings version did not match the header we built against\\n");
-       DEBUG_PRINT("Loaded LDK-Java Bindings with LDK %s and LDK-C-Bindings %s\\n", check_get_ldk_version(), check_get_ldk_bindings_version());
 }
 """
 
@@ -555,6 +574,9 @@ import javax.annotation.Nullable;
         self.file_ext = ".java"
         self.ptr_c_ty = "int64_t"
         self.ptr_native_ty = "long"
+        self.usize_c_ty = "int64_t"
+        self.usize_native_ty = "long"
+        self.native_zero_ptr = "0"
         self.result_c_ty = "jclass"
         self.ptr_arr = "jobjectArray"
         self.is_arr_some_check = ("", " != NULL")
@@ -680,11 +702,12 @@ import javax.annotation.Nullable;
     def cleanup_converted_native_array(self, ty_info, arr_name):
         return None
 
-    def primitive_arr_from_hu(self, mapped_ty, fixed_len, arr_name):
+    def primitive_arr_from_hu(self, arr_ty, fixed_len, arr_name):
+        mapped_ty = arr_ty.subty
         if fixed_len is not None:
             return ("InternalUtils.check_arr_len(" + arr_name + ", " + fixed_len + ")", "")
         return None
-    def primitive_arr_to_hu(self, primitive_ty, fixed_len, arr_name, conv_name):
+    def primitive_arr_to_hu(self, arr_ty, fixed_len, arr_name, conv_name):
         return None
 
     def java_arr_ty_str(self, elem_ty_str):
@@ -701,14 +724,14 @@ import javax.annotation.Nullable;
         return var + ".ptr" + " = 0;"
 
     def add_ref(self, holder, referent):
-        return holder + ".ptrs_to.add(" + referent + ")"
+        return "if (" + holder + " != null) { " + holder + ".ptrs_to.add(" + referent + "); }"
 
     def fully_qualified_hu_ty_path(self, ty):
         if ty.java_fn_ty_arg.startswith("L") and ty.java_fn_ty_arg.endswith(";"):
             return ty.java_fn_ty_arg.strip("L;").replace("/", ".")
         if ty.java_hu_ty == "UnqualifiedError" or ty.java_hu_ty == "UInt5" or ty.java_hu_ty == "WitnessVersion":
             return "org.ldk.util." + ty.java_hu_ty
-        if ty.rust_obj is not None and not "[]" in ty.java_hu_ty:
+        if not ty.is_native_primitive and ty.rust_obj is not None and not "[]" in ty.java_hu_ty:
             return "org.ldk.structs." + ty.java_hu_ty
         return ty.java_hu_ty
 
@@ -989,8 +1012,8 @@ import javax.annotation.Nullable;
                 if fn_line.ret_ty_info.c_ty.endswith("Array"):
                     out_c = out_c + "\t" + fn_line.ret_ty_info.c_ty + " ret = (*env)->CallObjectMethod(env, obj, j_calls->" + fn_line.fn_name + "_meth"
                 elif fn_line.ret_ty_info.c_ty == "void":
-                    out_c += "\t(*env)->Call" + fn_line.ret_ty_info.java_ty.title() + "Method(env, obj, j_calls->" + fn_line.fn_name + "_meth"
-                elif fn_line.ret_ty_info.java_hu_ty == "String":
+                    out_c += "\t(*env)->CallVoidMethod(env, obj, j_calls->" + fn_line.fn_name + "_meth"
+                elif fn_line.ret_ty_info.java_hu_ty == "String" or "org/ldk/enums" in fn_line.ret_ty_info.java_fn_ty_arg:
                     # Manually write out String methods as they're just an Object
                     out_c += "\t" + fn_line.ret_ty_info.c_ty + " ret = (*env)->CallObjectMethod(env, obj, j_calls->" + fn_line.fn_name + "_meth"
                 elif not fn_line.ret_ty_info.passed_as_ptr:
@@ -1105,7 +1128,7 @@ import javax.annotation.Nullable;
             else:
                 out_c = out_c + ", " + var[1]
         out_c = out_c + ");\n"
-        out_c = out_c + "\treturn (uint64_t)res_ptr;\n"
+        out_c = out_c + "\treturn tag_ptr(res_ptr, true);\n"
         out_c = out_c + "}\n"
 
         for var in flattened_field_vars:
@@ -1124,10 +1147,8 @@ import javax.annotation.Nullable;
                 out_java += "\tpublic static native long " + struct_name + "_get_" + var[1] + "(long arg);\n"
 
                 out_c += "JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_" + struct_name + "_1get_1" + var[1] + "(JNIEnv *env, jclass clz, int64_t arg) {\n"
-                out_c += "\t" + struct_name + " *inp = (" + struct_name + " *)(arg & ~1);\n"
-                out_c += "\tuint64_t res_ptr = (uint64_t)&inp->" + var[1] + ";\n"
-                out_c += "\tDO_ASSERT((res_ptr & 1) == 0);\n"
-                out_c += "\treturn (int64_t)(res_ptr | 1);\n"
+                out_c += "\t" + struct_name + " *inp = (" + struct_name + " *)untag_ptr(arg);\n"
+                out_c += "\treturn tag_ptr(&inp->" + var[1] + ", false);\n"
                 out_c += "}\n"
 
         return (out_java, out_java_trait, out_c)
@@ -1217,7 +1238,7 @@ import javax.annotation.Nullable;
         out_c += (self.c_complex_enum_pfx(struct_name, [x.var_name for x in variant_list], init_meth_jty_strs))
 
         out_c += (self.c_fn_ty_pfx + self.c_complex_enum_pass_ty(struct_name) + " " + self.c_fn_name_define_pfx(struct_name + "_ref_from_ptr", True) + self.ptr_c_ty + " ptr) {\n")
-        out_c += ("\t" + struct_name + " *obj = (" + struct_name + "*)(ptr & ~1);\n")
+        out_c += ("\t" + struct_name + " *obj = (" + struct_name + "*)untag_ptr(ptr);\n")
         out_c += ("\tswitch(obj->tag) {\n")
         for var in variant_list:
             out_c += ("\t\tcase " + struct_name + "_" + var.var_name + ": {\n")
@@ -1249,11 +1270,11 @@ import javax.annotation.Nullable;
         out_opaque_struct_human += "@SuppressWarnings(\"unchecked\") // We correctly assign various generic arrays\n"
         hu_name = struct_name.replace("LDKC2Tuple", "TwoTuple").replace("LDKC3Tuple", "ThreeTuple").replace("LDK", "")
         out_opaque_struct_human += ("public class " + hu_name + " extends CommonBase")
-        if struct_name.startswith("LDKLocked"):
+        if struct_name.startswith("LDKLocked") or struct_name.startswith("LDKReadOnly"):
             out_opaque_struct_human += (" implements AutoCloseable")
         out_opaque_struct_human += (" {\n")
         out_opaque_struct_human += ("\t" + hu_name + "(Object _dummy, long ptr) { super(ptr); }\n")
-        if struct_name.startswith("LDKLocked"):
+        if struct_name.startswith("LDKLocked") or struct_name.startswith("LDKReadOnly"):
             out_opaque_struct_human += ("\t@Override public void close() {\n")
         else:
             out_opaque_struct_human += ("\t@Override @SuppressWarnings(\"deprecation\")\n")