Support new cloned upstream API instead of clone
authorMatt Corallo <git@bluematt.me>
Sun, 18 Jul 2021 02:24:07 +0000 (02:24 +0000)
committerMatt Corallo <git@bluematt.me>
Sun, 18 Jul 2021 03:17:52 +0000 (03:17 +0000)
genbindings.py
java_strings.py
typescript_strings.py

index 35a3be01a2259b1a4f9ec596da93763c4eef9516..5e8071ec00b31e1c93a9d6a05ef69d9dbc043e37 100755 (executable)
@@ -570,16 +570,20 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
 
             field_fns = []
             for fn_docs, fn_line in trait_fn_lines:
-                ret_ty_info = type_mapping_generator.map_type(fn_line.group(2).strip() + " ret", True, None, False, False)
-                is_const = fn_line.group(4) is not None
+                if fn_line == "cloned":
+                    ret_ty_info = type_mapping_generator.map_type("void", True, None, False, False)
+                    field_fns.append(TraitMethInfo("cloned", False, ret_ty_info, [], fn_docs))
+                else:
+                    ret_ty_info = type_mapping_generator.map_type(fn_line.group(2).strip() + " ret", True, None, False, False)
+                    is_const = fn_line.group(4) is not None
 
-                arg_tys = []
-                for idx, arg in enumerate(fn_line.group(5).split(',')):
-                    if arg == "":
-                        continue
-                    arg_conv_info = type_mapping_generator.map_type(arg, True, None, False, False)
-                    arg_tys.append(arg_conv_info)
-                field_fns.append(TraitMethInfo(fn_line.group(3), is_const, ret_ty_info, arg_tys, fn_docs))
+                    arg_tys = []
+                    for idx, arg in enumerate(fn_line.group(5).split(',')):
+                        if arg == "":
+                            continue
+                        arg_conv_info = type_mapping_generator.map_type(arg, True, None, False, False)
+                        arg_tys.append(arg_conv_info)
+                    field_fns.append(TraitMethInfo(fn_line.group(3), is_const, ret_ty_info, arg_tys, fn_docs))
 
             (out_java_addendum, out_java_trait_addendum, out_c_addendum) = consts.native_c_map_trait(struct_name, field_var_convs, flattened_field_var_convs, field_fns, trait_doc_comment)
             write_c(out_c_addendum)
@@ -587,9 +591,11 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
             out_java.write(out_java_addendum)
 
         for fn_docs, fn_line in trait_fn_lines:
+            if fn_line == "cloned":
+                continue
             # For now, just disable enabling the _call_log - we don't know how to inverse-map String
             is_log = fn_line.group(3) == "log" and struct_name == "LDKLogger"
-            if fn_line.group(3) != "free" and fn_line.group(3) != "clone" and fn_line.group(3) != "eq" and not is_log:
+            if fn_line.group(3) != "free" and fn_line.group(3) != "eq" and not is_log:
                 dummy_line = fn_line.group(2) + struct_name.replace("LDK", "") + "_" + fn_line.group(3) + " " + struct_name + " *NONNULL_PTR this_arg" + fn_line.group(5) + "\n"
                 map_fn(dummy_line, re.compile("([A-Za-z_0-9]*) *([A-Za-z_0-9]*) *(.*)").match(dummy_line), None, "(this_arg_conv->" + fn_line.group(3) + ")(this_arg_conv->this_arg", fn_docs)
         for idx, var_line in enumerate(field_var_lines):
@@ -750,8 +756,9 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
     line_indicates_trait_regex = re.compile("^   (struct |enum |union )?([A-Za-z_0-9]* \*?)\(\*([A-Za-z_0-9]*)\)\((const )?void \*this_arg(.*)\);$")
     assert(line_indicates_trait_regex.match("   uintptr_t (*send_data)(void *this_arg, LDKu8slice data, bool resume_read);"))
     assert(line_indicates_trait_regex.match("   struct LDKCVec_MessageSendEventZ (*get_and_clear_pending_msg_events)(const void *this_arg);"))
-    assert(line_indicates_trait_regex.match("   void *(*clone)(const void *this_arg);"))
     assert(line_indicates_trait_regex.match("   struct LDKCVec_u8Z (*write)(const void *this_arg);"))
+    line_indicates_trait_clone_regex = re.compile("^   void \(\*cloned\)\(struct ([A-Za-z0-9])* \*NONNULL_PTR new_[A-Za-z0-9]*\);$")
+    assert(line_indicates_trait_clone_regex.match("   void (*cloned)(struct LDKSign *NONNULL_PTR new_Sign);"))
     line_field_var_regex = re.compile("^   struct ([A-Za-z_0-9]*) ([A-Za-z_0-9]*);$")
     assert(line_field_var_regex.match("   struct LDKMessageSendEventsProvider MessageSendEventsProvider;"))
     assert(line_field_var_regex.match("   struct LDKChannelPublicKeys pubkeys;"))
@@ -817,6 +824,9 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java:
                         trait_fn_match = line_indicates_trait_regex.match(struct_line)
                         if trait_fn_match is not None:
                             trait_fn_lines.append((last_struct_block_comment, trait_fn_match))
+                        trait_clone_fn_match = line_indicates_trait_clone_regex.match(struct_line)
+                        if trait_clone_fn_match is not None:
+                            trait_fn_lines.append((last_struct_block_comment, "cloned"))
                         field_var_match = line_field_var_regex.match(struct_line)
                         if field_var_match is not None:
                             field_var_lines.append(field_var_match)
index f97ca9b7d0cff3ac4b416f175c8add0d10c9d040..7cd486aafeb6ba8d780cf5630bf74706e888fb72 100644 (file)
@@ -708,7 +708,7 @@ import java.util.Arrays;
         java_meths = []
         for fn_line in field_fns:
             java_meth_descr = "("
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 out_java = out_java + "\t\t " + fn_line.ret_ty_info.java_ty + " " + fn_line.fn_name + "("
                 java_trait_constr = java_trait_constr + "\t\t\t@Override public " + fn_line.ret_ty_info.java_ty + " " + fn_line.fn_name + "("
                 out_java_trait += "\t\t/**\n\t\t * " + fn_line.docs.replace("\n", "\n\t\t * ") + "\n\t\t */\n"
@@ -801,7 +801,7 @@ import java.util.Arrays;
                 # We're a supertrait
                 out_c = out_c + "\t" + var[0] + "_JCalls* " + var[1] + ";\n"
         for fn in field_fns:
-            if fn.fn_name != "free" and fn.fn_name != "clone":
+            if fn.fn_name != "free" and fn.fn_name != "cloned":
                 out_c = out_c + "\tjmethodID " + fn.fn_name + "_meth;\n"
         out_c = out_c + "} " + struct_name + "_JCalls;\n"
 
@@ -817,7 +817,7 @@ import java.util.Arrays;
                 out_c = out_c + "\t}\n}\n"
 
         for idx, fn_line in enumerate(field_fns):
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 assert fn_line.ret_ty_info.ty_info.get_full_rust_ty()[1] == ""
                 out_c = out_c + fn_line.ret_ty_info.ty_info.get_full_rust_ty()[0] + " " + fn_line.fn_name + "_" + struct_name + "_jcall("
                 if fn_line.self_is_const:
@@ -871,15 +871,19 @@ import java.util.Arrays;
 
                 out_c = out_c + "}\n"
 
-        # Write out a clone function whether we need one or not, as we use them in moving to rust
-        out_c = out_c + "static void* " + struct_name + "_JCalls_clone(const void* this_arg) {\n"
-        out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) this_arg;\n"
-        out_c = out_c + "\tatomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);\n"
+        # If we can, write out a clone function whether we need one or not, as we use them in moving to rust
+        can_clone_with_ptr = True
         for var in field_vars:
-            if not isinstance(var, ConvInfo):
-                out_c = out_c + "\tatomic_fetch_add_explicit(&j_calls->" + var[1] + "->refcnt, 1, memory_order_release);\n"
-        out_c = out_c + "\treturn (void*) this_arg;\n"
-        out_c = out_c + "}\n"
+            if isinstance(var, ConvInfo):
+                can_clone_with_ptr = False
+        if can_clone_with_ptr:
+            out_c = out_c + "static void " + struct_name + "_JCalls_cloned(" + struct_name + "* new_obj) {\n"
+            out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) new_obj->this_arg;\n"
+            out_c = out_c + "\tatomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);\n"
+            for var in field_vars:
+                if not isinstance(var, ConvInfo):
+                    out_c = out_c + "\tatomic_fetch_add_explicit(&j_calls->" + var[1] + "->refcnt, 1, memory_order_release);\n"
+            out_c = out_c + "}\n"
 
         out_c = out_c + "static inline " + struct_name + " " + struct_name + "_init (" + self.c_fn_args_pfx + ", jobject o"
         for var in flattened_field_vars:
@@ -897,7 +901,7 @@ import java.util.Arrays;
         out_c = out_c + "\tcalls->o = (*env)->NewWeakGlobalRef(env, o);\n"
 
         for (fn_name, java_meth_descr) in java_meths:
-            if fn_name != "free" and fn_name != "clone":
+            if fn_name != "free" and fn_name != "cloned":
                 out_c = out_c + "\tcalls->" + fn_name + "_meth = (*env)->GetMethodID(env, c, \"" + fn_name + "\", \"" + java_meth_descr + "\");\n"
                 out_c = out_c + "\tCHECK(calls->" + fn_name + "_meth != NULL);\n"
 
@@ -907,12 +911,12 @@ import java.util.Arrays;
         out_c = out_c + "\n\t" + struct_name + " ret = {\n"
         out_c = out_c + "\t\t.this_arg = (void*) calls,\n"
         for fn_line in field_fns:
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 out_c = out_c + "\t\t." + fn_line.fn_name + " = " + fn_line.fn_name + "_" + struct_name + "_jcall,\n"
             elif fn_line.fn_name == "free":
                 out_c = out_c + "\t\t.free = " + struct_name + "_JCalls_free,\n"
             else:
-                out_c = out_c + "\t\t.clone = " + struct_name + "_JCalls_clone,\n"
+                out_c = out_c + "\t\t.cloned = " + struct_name + "_JCalls_cloned,\n"
         for var in field_vars:
             if isinstance(var, ConvInfo):
                 if var.arg_conv_name is not None:
@@ -959,7 +963,7 @@ import java.util.Arrays;
     def trait_struct_inc_refcnt(self, ty_info):
         base_conv = "\nif (" + ty_info.var_name + "_conv.free == " + ty_info.rust_obj + "_JCalls_free) {\n"
         base_conv = base_conv + "\t// If this_arg is a JCalls struct, then we need to increment the refcnt in it.\n"
-        base_conv = base_conv + "\t" + ty_info.rust_obj + "_JCalls_clone(" + ty_info.var_name + "_conv.this_arg);\n}"
+        base_conv = base_conv + "\t" + ty_info.rust_obj + "_JCalls_cloned(&" + ty_info.var_name + "_conv);\n}"
         return base_conv
 
     def map_complex_enum(self, struct_name, variant_list, camel_to_snake, enum_doc_comment):
index b9eaf6abb3880e0896cbc12374040b0f393c33fe..625716806f5f15c516286d0ac8ac7a9389151ca8 100644 (file)
@@ -525,7 +525,7 @@ const decodeString = (stringPointer, free = true) => {
         java_methods = []
         for fn_line in field_function_lines:
             java_method_descriptor = ""
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 out_java_interface += fn_line.fn_name + "("
                 out_interface_implementation_overrides += f"{fn_line.fn_name} ("
 
@@ -642,7 +642,7 @@ const decodeString = (stringPointer, free = true) => {
         out_typescript_bindings += "\t\texport interface " + struct_name + " {\n"
         java_meths = []
         for fn_line in field_function_lines:
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 out_typescript_bindings += f"\t\t\t{fn_line.fn_name} ("
 
                 for idx, arg_conv_info in enumerate(fn_line.args_ty):
@@ -679,7 +679,7 @@ const decodeString = (stringPointer, free = true) => {
                 # We're a supertrait
                 out_c = out_c + "\t" + var[0] + "_JCalls* " + var[1] + ";\n"
         for fn in field_function_lines:
-            if fn.fn_name != "free" and fn.fn_name != "clone":
+            if fn.fn_name != "free" and fn.fn_name != "cloned":
                 out_c = out_c + "\tuint32_t " + fn.fn_name + "_meth;\n"
         out_c = out_c + "} " + struct_name + "_JCalls;\n"
 
@@ -689,13 +689,13 @@ const decodeString = (stringPointer, free = true) => {
                 out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) this_arg;\n"
                 out_c = out_c + "\tif (atomic_fetch_sub_explicit(&j_calls->refcnt, 1, memory_order_acquire) == 1) {\n"
                 for fn in field_function_lines:
-                    if fn.fn_name != "free" and fn.fn_name != "clone":
+                    if fn.fn_name != "free" and fn.fn_name != "cloned":
                         out_c = out_c + "\t\tjs_free(j_calls->" + fn.fn_name + "_meth);\n"
                 out_c = out_c + "\t\tFREE(j_calls);\n"
                 out_c = out_c + "\t}\n}\n"
 
         for idx, fn_line in enumerate(field_function_lines):
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 assert fn_line.ret_ty_info.ty_info.get_full_rust_ty()[1] == ""
                 out_c = out_c + fn_line.ret_ty_info.ty_info.get_full_rust_ty()[0] + " " + fn_line.fn_name + "_" + struct_name + "_jcall("
                 if fn_line.self_is_const:
@@ -736,8 +736,8 @@ const decodeString = (stringPointer, free = true) => {
                 out_c = out_c + "}\n"
 
         # Write out a clone function whether we need one or not, as we use them in moving to rust
-        out_c = out_c + "static void* " + struct_name + "_JCalls_clone(const void* this_arg) {\n"
-        out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) this_arg;\n"
+        out_c = out_c + "static void " + struct_name + "_JCalls_cloned(" + struct_name + "* new_obj) {\n"
+        out_c = out_c + "\t" + struct_name + "_JCalls *j_calls = (" + struct_name + "_JCalls*) new_obj->this_arg;\n"
         out_c = out_c + "\tatomic_fetch_add_explicit(&j_calls->refcnt, 1, memory_order_release);\n"
         for var in field_var_conversions:
             if not isinstance(var, ConvInfo):
@@ -758,7 +758,7 @@ const decodeString = (stringPointer, free = true) => {
         out_c = out_c + "\t//TODO: Assign calls->o from o\n"
 
         for (fn_name, java_meth_descr) in java_meths:
-            if fn_name != "free" and fn_name != "clone":
+            if fn_name != "free" and fn_name != "cloned":
                 out_c = out_c + "\tcalls->" + fn_name + "_meth = (*env)->GetMethodID(env, c, \"" + fn_name + "\", \"" + java_meth_descr + "\");\n"
                 out_c = out_c + "\tCHECK(calls->" + fn_name + "_meth != NULL);\n"
 
@@ -768,12 +768,12 @@ const decodeString = (stringPointer, free = true) => {
         out_c = out_c + "\n\t" + struct_name + " ret = {\n"
         out_c = out_c + "\t\t.this_arg = (void*) calls,\n"
         for fn_line in field_function_lines:
-            if fn_line.fn_name != "free" and fn_line.fn_name != "clone":
+            if fn_line.fn_name != "free" and fn_line.fn_name != "cloned":
                 out_c = out_c + "\t\t." + fn_line.fn_name + " = " + fn_line.fn_name + "_" + struct_name + "_jcall,\n"
             elif fn_line.fn_name == "free":
                 out_c = out_c + "\t\t.free = " + struct_name + "_JCalls_free,\n"
             else:
-                out_c = out_c + "\t\t.clone = " + struct_name + "_JCalls_clone,\n"
+                out_c = out_c + "\t\t.cloned = " + struct_name + "_JCalls_cloned,\n"
         for var in field_var_conversions:
             if isinstance(var, ConvInfo):
                 if var.arg_conv_name is not None: