Handle calls which take strings as an argument in Java
authorMatt Corallo <git@bluematt.me>
Thu, 22 Apr 2021 16:29:50 +0000 (16:29 +0000)
committerMatt Corallo <git@bluematt.me>
Thu, 22 Apr 2021 17:04:47 +0000 (17:04 +0000)
gen_type_mapping.py
java_strings.py
typescript_strings.py

index 8863462f8f149db270ce08622877c4d33b4992b4..3e0d9aeef86b7a5578d5d9a3009925a5e78193bd 100644 (file)
@@ -171,18 +171,24 @@ class TypeMappingGenerator:
                     arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = arg_conv_cleanup,
                     ret_conv = ret_conv, ret_conv_name = arr_name + "_arr", to_hu_conv = to_hu_conv, to_hu_conv_name = to_hu_conv_name, from_hu_conv = from_hu_conv)
         elif ty_info.java_ty == "String":
+            if not is_free:
+                arg_conv = "LDKStr " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_c_call(ty_info.var_name) + ";"
+                arg_conv_name = ty_info.var_name + "_conv"
+            else:
+                arg_conv = "LDKStr dummy = { .chars = NULL, .len = 0, .chars_is_owned = false };"
+                arg_conv_name = "dummy"
             if ty_info.arr_access is None:
                 return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
-                    arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
+                    arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = None,
                     ret_conv = ("const char* " + ty_info.var_name + "_str = ",
-                        ";\njstring " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_c_call(ty_info.var_name + "_str", "strlen(" + ty_info.var_name + "_str)") + ";"),
+                        ";\njstring " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_native_call(ty_info.var_name + "_str", "strlen(" + ty_info.var_name + "_str)") + ";"),
                     ret_conv_name = ty_info.var_name + "_conv",
                     to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
             else:
                 return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
-                    arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
+                    arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = None,
                     ret_conv = ("LDKStr " + ty_info.var_name + "_str = ",
-                        ";\njstring " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_c_call(ty_info.var_name + "_str." + ty_info.arr_access, ty_info.var_name + "_str." + ty_info.arr_len) + ";"),
+                        ";\njstring " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_native_call(ty_info.var_name + "_str." + ty_info.arr_access, ty_info.var_name + "_str." + ty_info.arr_len) + ";"),
                     ret_conv_name = ty_info.var_name + "_conv", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
         elif ty_info.var_name == "" and not print_void:
             # We don't have a parameter name, and want one, just call it arg
index af7672b00b53676af0c8c58d6553e034232a4894..96d6909678ce7e58997f7866a4af65b0db8b40ef 100644 (file)
@@ -315,6 +315,20 @@ static inline jstring str_ref_to_java(JNIEnv *env, const char* chars, size_t len
        FREE(err_buf);
        return err_conv;
 }
+static inline LDKStr java_to_owned_str(JNIEnv *env, jstring str) {
+       uint64_t str_len = (*env)->GetStringUTFLength(env, str);
+       char* newchars = MALLOC(str_len + 1, "String chars");
+       const char* jchars = (*env)->GetStringUTFChars(env, str, NULL);
+       memcpy(newchars, jchars, str_len);
+       newchars[str_len] = 0;
+       (*env)->ReleaseStringUTFChars(env, str, jchars);
+       LDKStr res = {
+               .chars = newchars,
+               .len = str_len,
+               .chars_is_owned = true
+       };
+       return res;
+}
 """
 
         self.hu_struct_file_prefix = """package org.ldk.structs;
@@ -381,8 +395,10 @@ import java.util.Arrays;
         else:
             return "(*env)->Release" + ty_info.java_ty.strip("[]").title() + "ArrayElements(env, " + arr_name + ", " + dest_name + ", 0)"
 
-    def str_ref_to_c_call(self, var_name, str_len):
+    def str_ref_to_native_call(self, var_name, str_len):
         return "str_ref_to_java(env, " + var_name + ", " + str_len + ")"
+    def str_ref_to_c_call(self, var_name):
+        return "java_to_owned_str(env, " + var_name + ")"
 
     def c_fn_name_define_pfx(self, fn_name, has_args):
         if has_args:
index 20f639fb8d80cf8e7bc8f35bfcefd70f78157826..4300f1f80064d3bcba2fadf9cce07fef41f3e471 100644 (file)
@@ -233,12 +233,24 @@ static inline uint32_t init_arr(size_t arr_len, size_t elem_size, const char *ty
        return (uint32_t)elems;
 }
 
-jstring str_ref_to_ts(const char* chars, size_t len) {
+static inline jstring str_ref_to_ts(const char* chars, size_t len) {
        char* err_buf = MALLOC(len + 4, "str conv buf");
        *((uint32_t*)err_buf) = len;
        memcpy(err_buf + 4, chars, len);
        return (uint32_t) err_buf;
 }
+static inline LDKStr str_ref_to_owned_c(jstring str) {
+       uint32_t *str_len = (uint32_t*)str;
+       char* newchars = MALLOC(*str_len + 1, "String chars");
+       memcpy(newchars, (const char*)(str + 4), *str_len);
+       newchars[*str_len] = 0;
+       LDKStr res= {
+               .chars = newchars,
+               .len = *str_len,
+               .chars_is_owned = true
+       };
+       return res;
+}
 
 typedef bool jboolean;
 
@@ -305,8 +317,10 @@ import * as bindings from '../bindings' // TODO: figure out location
         else:
             return None
 
-    def str_ref_to_c_call(self, var_name, str_len):
+    def str_ref_to_native_call(self, var_name, str_len):
         return "str_ref_to_ts(" + var_name + ", " + str_len + ")"
+    def str_ref_to_c_call(self, var_name):
+        return "str_ref_to_owned_c(" + var_name + ")"
 
     def c_fn_name_define_pfx(self, fn_name, have_args):
         return " __attribute__((visibility(\"default\"))) TS_" + fn_name + "("