Skip manual leak checking on OSX as -Wl,-wrap is too complicated
[ldk-java] / java_strings.py
index 94998db17a6dbade2c919bc505ca3a7b9821236f..6bfd571bbf991caa8b5be640b409ce0ab33ac1d3 100644 (file)
@@ -1,5 +1,6 @@
 from bindingstypes import *
 from enum import Enum
+import sys
 
 class Target(Enum):
     JAVA = 1,
@@ -83,11 +84,13 @@ class CommonBase {
        long ptr;
        LinkedList<Object> ptrs_to = new LinkedList();
        protected CommonBase(long ptr) { this.ptr = ptr; }
-       public long _test_only_get_ptr() { return this.ptr; }
 }
 """
 
-        self.c_file_pfx = """#include \"org_ldk_impl_bindings.h\"
+        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
+#include \"org_ldk_impl_bindings.h\"
 #include <lightning.h>
 #include <string.h>
 #include <stdatomic.h>
@@ -124,13 +127,15 @@ void __attribute__((constructor)) spawn_stderr_redirection() {
         else:
             self.c_file_pfx = self.c_file_pfx + "#define DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__)\n"
 
-        if not DEBUG:
+        if not DEBUG or sys.platform == "darwin":
             self.c_file_pfx = self.c_file_pfx + """#define MALLOC(a, _) malloc(a)
 #define FREE(p) if ((uint64_t)(p) > 1024) { free(p); }
-#define DO_ASSERT(a) (void)(a)
+"""
+        if not DEBUG:
+            self.c_file_pfx += """#define DO_ASSERT(a) (void)(a)
 #define CHECK(a)
 """
-        else:
+        if DEBUG:
             self.c_file_pfx = self.c_file_pfx + """#include <assert.h>
 // Always run a, then assert it is true:
 #define DO_ASSERT(a) do { bool _assert_val = (a); assert(_assert_val); } while(0)
@@ -144,7 +149,10 @@ void __attribute__((constructor)) debug_log_version() {
                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());
 }
+"""
 
+            if sys.platform != "darwin":
+                self.c_file_pfx += """
 // Running a leak check across all the allocations and frees of the JDK is a mess,
 // so instead we implement our own naive leak checker here, relying on the -wrap
 // linker option to wrap malloc/calloc/realloc/free, tracking everyhing allocated
@@ -152,8 +160,8 @@ void __attribute__((constructor)) debug_log_version() {
 #include <threads.h>
 """
 
-            if self.target == Target.ANDROID:
-                self.c_file_pfx = self.c_file_pfx + """
+                if self.target == Target.ANDROID:
+                    self.c_file_pfx = self.c_file_pfx + """
 #include <unwind.h>
 #include <dlfcn.h>
 
@@ -194,9 +202,9 @@ void backtrace_symbols_fd(void ** buffer, int count, int _fd) {
        }
 }
 """
-            else:
-                self.c_file_pfx = self.c_file_pfx + "#include <execinfo.h>\n"
-            self.c_file_pfx = self.c_file_pfx + """
+                else:
+                    self.c_file_pfx = self.c_file_pfx + "#include <execinfo.h>\n"
+                self.c_file_pfx = self.c_file_pfx + """
 #include <unistd.h>
 static mtx_t allocation_mtx;
 
@@ -457,7 +465,10 @@ import java.util.Arrays;
         res =  "JNIEnv *env;\n"
         res += "jint get_jenv_res = (*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_6);\n"
         res += "if (get_jenv_res == JNI_EDETACHED) {\n"
-        res += "\tDO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);\n"
+        if self.target == Target.ANDROID:
+            res += "\tDO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, &env, NULL) == JNI_OK);\n"
+        else:
+            res += "\tDO_ASSERT((*j_calls->vm)->AttachCurrentThread(j_calls->vm, (void**)&env, NULL) == JNI_OK);\n"
         res += "} else {\n"
         res += "\tDO_ASSERT(get_jenv_res == JNI_OK);\n"
         res += "}\n"
@@ -541,7 +552,7 @@ import java.util.Arrays;
         out_java_enum = "package org.ldk.enums;\n\n"
         out_java = ""
         out_c = ""
-        out_c = out_c + "static inline " + struct_name + " " + struct_name + "_from_java(" + self.c_fn_args_pfx + ") {\n"
+        out_c = out_c + "static inline LDK" + struct_name + " LDK" + struct_name + "_from_java(" + self.c_fn_args_pfx + ") {\n"
         out_c = out_c + "\tswitch ((*env)->CallIntMethod(env, clz, ordinal_meth)) {\n"
 
         if enum_doc_comment is not None:
@@ -570,7 +581,7 @@ import java.util.Arrays;
             out_c = out_c + "\t" + struct_name + "_" + var + " = (*env)->GetStaticFieldID(env, " + struct_name + "_class, \"" + var + "\", \"Lorg/ldk/enums/" + struct_name + ";\");\n"
             out_c = out_c + "\tCHECK(" + struct_name + "_" + var + " != NULL);\n"
         out_c = out_c + "}\n"
-        out_c = out_c + "static inline jclass " + struct_name + "_to_java(JNIEnv *env, " + struct_name + " val) {\n"
+        out_c = out_c + "static inline jclass LDK" + struct_name + "_to_java(JNIEnv *env, LDK" + struct_name + " val) {\n"
         out_c = out_c + "\tswitch (val) {\n"
         ord_v = 0
         for var in variants:
@@ -956,8 +967,19 @@ import java.util.Arrays;
             init_meth_body = ""
             hu_conv_body = ""
             for idx, field_ty in enumerate(var.fields):
-                out_java += ("\t\t\tpublic " + field_ty.java_ty + " " + field_ty.arg_name + ";\n")
-                java_hu_subclasses = java_hu_subclasses + "\t\tpublic final " + field_ty.java_hu_ty + " " + field_ty.arg_name + ";\n"
+                if idx > 0:
+                    init_meth_params = init_meth_params + ", "
+
+                if field_ty.java_hu_ty == var.var_name:
+                    field_path = field_ty.java_fn_ty_arg.strip("L;").replace("/", ".")
+                    out_java += "\t\t\tpublic " + field_path + " " + field_ty.arg_name + ";\n"
+                    java_hu_subclasses = java_hu_subclasses + "\t\tpublic final " + field_path + " " + field_ty.arg_name + ";\n"
+                    init_meth_params = init_meth_params + field_path + " " + field_ty.arg_name
+                else:
+                    out_java += "\t\t\tpublic " + field_ty.java_ty + " " + field_ty.arg_name + ";\n"
+                    java_hu_subclasses = java_hu_subclasses + "\t\tpublic final " + field_ty.java_hu_ty + " " + field_ty.arg_name + ";\n"
+                    init_meth_params = init_meth_params + field_ty.java_ty + " " + field_ty.arg_name
+                init_meth_body = init_meth_body + "this." + field_ty.arg_name + " = " + field_ty.arg_name + "; "
                 if field_ty.to_hu_conv is not None:
                     hu_conv_body = hu_conv_body + "\t\t\t" + field_ty.java_ty + " " + field_ty.arg_name + " = obj." + field_ty.arg_name + ";\n"
                     hu_conv_body = hu_conv_body + "\t\t\t" + field_ty.to_hu_conv.replace("\n", "\n\t\t\t") + "\n"
@@ -965,10 +987,6 @@ import java.util.Arrays;
                 else:
                     hu_conv_body = hu_conv_body + "\t\t\tthis." + field_ty.arg_name + " = obj." + field_ty.arg_name + ";\n"
                 init_meth_jty_str = init_meth_jty_str + field_ty.java_fn_ty_arg
-                if idx > 0:
-                    init_meth_params = init_meth_params + ", "
-                init_meth_params = init_meth_params + field_ty.java_ty + " " + field_ty.arg_name
-                init_meth_body = init_meth_body + "this." + field_ty.arg_name + " = " + field_ty.arg_name + "; "
             out_java +=  ("\t\t\t" + var.var_name + "(" + init_meth_params + ") { ")
             out_java +=  (init_meth_body)
             out_java +=  ("}\n")
@@ -1034,7 +1052,7 @@ import java.util.Arrays;
         return out_opaque_struct_human
 
 
-    def map_function(self, argument_types, c_call_string, method_name, return_type_info, struct_meth, default_constructor_args, takes_self, args_known, type_mapping_generator, doc_comment):
+    def map_function(self, argument_types, c_call_string, method_name, return_type_info, struct_meth, default_constructor_args, takes_self, takes_self_as_ref, args_known, type_mapping_generator, doc_comment):
         out_java = ""
         out_c = ""
         out_java_struct = None
@@ -1061,7 +1079,7 @@ import java.util.Arrays;
         if not args_known:
             out_java_struct += ("\t// Skipped " + method_name + "\n")
         else:
-            meth_n = method_name[len(struct_meth) + 1:].strip("_")
+            meth_n = method_name[len(struct_meth) + 1 if len(struct_meth) != 0 else 0:].strip("_")
             if doc_comment is not None:
                 out_java_struct += "\t/**\n\t * " + doc_comment.replace("\n", "\n\t * ") + "\n\t */\n"
             if not takes_self:
@@ -1076,7 +1094,7 @@ import java.util.Arrays;
             for idx, arg in enumerate(argument_types):
                 if idx != 0:
                     if not takes_self or idx > 1:
-                        out_java_struct += (", ")
+                        out_java_struct += ", "
                 elif takes_self:
                     continue
                 if arg.java_ty != "void":
@@ -1177,6 +1195,8 @@ import java.util.Arrays;
                     else:
                         out_java_struct += ("\t\t" + info.from_hu_conv[1].replace("\n", "\n\t\t") + ";\n")
 
+            if takes_self and not takes_self_as_ref:
+                out_java_struct += "\t\t" + argument_types[0].from_hu_conv[1].replace("\n", "\n\t\t").replace("this_arg", "this") + ";\n"
             if return_type_info.to_hu_conv_name is not None:
                 out_java_struct += ("\t\treturn " + return_type_info.to_hu_conv_name + ";\n")
             elif return_type_info.java_ty != "void" and return_type_info.rust_obj != "LDK" + struct_meth: