conv_name = "arr_conv_" + str(len(ty_info.java_hu_ty))
idxc = chr(ord('a') + (len(ty_info.java_hu_ty) % 26))
ty_info.subty.var_name = conv_name
+ ty_info.subty.passed_as_ptr = False
subty = map_type_with_info(ty_info.subty, False, None, is_free, holds_ref)
if arr_name == "":
arr_name = "arg"
"jstring " + ty_info.var_name + "_conv = (*_env)->NewStringUTF(_env, " + ty_info.var_name + "_str." + ty_info.arr_access + ");\n" +
"FREE(" + ty_info.var_name + "_buf);"),
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 != "":
- # If we have a parameter name, print it (noting that it may indicate its a pointer)
- if ty_info.rust_obj is not None:
- assert(ty_info.passed_as_ptr)
- opaque_arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv;\n"
- opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.inner = (void*)(" + ty_info.var_name + " & (~1));\n"
- opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.is_owned = (" + ty_info.var_name + " & 1) || (" + ty_info.var_name + " == 0);"
- if not ty_info.is_ptr and not is_free and not ty_info.pass_by_ref:
- if (ty_info.java_hu_ty + "_clone") in clone_fns:
- # TODO: This is a bit too naive, even with the checks above, we really need to know if rust wants a ref or not, not just if its pass as a ptr.
- opaque_arg_conv = opaque_arg_conv + "\nif (" + ty_info.var_name + "_conv.inner != NULL)\n"
- opaque_arg_conv = opaque_arg_conv + "\t" + ty_info.var_name + "_conv = " + ty_info.java_hu_ty + "_clone(&" + ty_info.var_name + "_conv);"
- elif ty_info.passed_as_ptr:
- opaque_arg_conv = opaque_arg_conv + "\n// Warning: we may need a move here but can't clone!"
- if not ty_info.is_ptr:
- if ty_info.rust_obj in unitary_enums:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = " + ty_info.rust_obj + "_from_java(_env, " + ty_info.var_name + ");",
- arg_conv_name = ty_info.var_name + "_conv",
- arg_conv_cleanup = None,
- ret_conv = ("jclass " + ty_info.var_name + "_conv = " + ty_info.rust_obj + "_to_java(_env, ", ");"),
- ret_conv_name = ty_info.var_name + "_conv", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
- if ty_info.rust_obj in opaque_structs:
- ret_conv_suf = ";\nCHECK((((long)" + ty_info.var_name + "_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.\n"
- ret_conv_suf = ret_conv_suf + "CHECK((((long)&" + ty_info.var_name + "_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.\n"
- if holds_ref:
- ret_conv_suf = ret_conv_suf + "long " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_var.inner & ~1;"
- else:
- ret_conv_suf = ret_conv_suf + "long " + ty_info.var_name + "_ref;\n"
- ret_conv_suf = ret_conv_suf + "if (" + ty_info.var_name + "_var.is_owned) {\n"
- ret_conv_suf = ret_conv_suf + "\t" + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_var.inner | 1;\n"
- ret_conv_suf = ret_conv_suf + "} else {\n"
- ret_conv_suf = ret_conv_suf + "\t" + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_var.inner & ~1;\n"
- ret_conv_suf = ret_conv_suf + "}"
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = opaque_arg_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = (ty_info.rust_obj + " " + ty_info.var_name + "_var = ", ret_conv_suf),
- ret_conv_name = ty_info.var_name + "_ref",
- to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = new " + ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
- to_hu_conv_name = ty_info.var_name + "_hu_conv",
- from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")"))
- base_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)" + ty_info.var_name + ";";
- if ty_info.rust_obj in trait_structs:
- if not is_free:
- base_conv = 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}"
- else:
- base_conv = base_conv + "\n" + "FREE((void*)" + ty_info.var_name + ");"
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = ("CANT PASS TRAIT TO Java?", ""), ret_conv_name = "NO CONV POSSIBLE",
- to_hu_conv = "DUMMY", to_hu_conv_name = None,
- from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr", "this.ptrs_to.add(" + ty_info.var_name + ")"))
- if ty_info.rust_obj != "LDKu8slice" and ty_info.rust_obj != "LDKTransaction":
- # Don't bother free'ing slices passed in - Rust doesn't auto-free the
- # underlying unlike Vecs, and it gives Java more freedom.
- base_conv = base_conv + "\nFREE((void*)" + ty_info.var_name + ");";
- if ty_info.rust_obj in complex_enums:
- ret_conv = ("long " + ty_info.var_name + "_ref = (long)&", ";")
- if not ty_info.is_ptr and not holds_ref and (ty_info.java_hu_ty + "_clone") in clone_fns:
- ret_conv = (ty_info.rust_obj + " *" + ty_info.var_name + "_copy = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n", "")
- ret_conv = (ret_conv[0] + "*" + ty_info.var_name + "_copy = " + ty_info.java_hu_ty + "_clone(&", ");\n")
- ret_conv = (ret_conv[0], ret_conv[1] + "long " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_copy;")
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = ret_conv, ret_conv_name = ty_info.var_name + "_ref",
- to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = " + ty_info.java_hu_ty + ".constr_from_ptr(" + ty_info.var_name + ");",
- to_hu_conv_name = ty_info.var_name + "_hu_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
- if ty_info.rust_obj in tuple_types:
- from_hu_conv = "bindings." + tuple_types[ty_info.rust_obj][1].replace("LDK", "") + "_new("
- to_hu_conv_pfx = ""
- to_hu_conv_sfx = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " + ty_info.java_hu_ty + "("
- for idx, conv in enumerate(tuple_types[ty_info.rust_obj][0]):
- if idx != 0:
- to_hu_conv_sfx = to_hu_conv_sfx + ", "
- from_hu_conv = from_hu_conv + ", "
- conv.var_name = ty_info.var_name + "_" + chr(idx + ord("a"))
- conv_map = map_type_with_info(conv, False, None, is_free, holds_ref)
- to_hu_conv_pfx = to_hu_conv_pfx + conv.java_ty + " " + ty_info.var_name + "_" + chr(idx + ord("a")) + " = " + "bindings." + tuple_types[ty_info.rust_obj][1] + "_get_" + chr(idx + ord("a")) + "(" + ty_info.var_name + ");\n"
- if conv_map.to_hu_conv is not None:
- to_hu_conv_pfx = to_hu_conv_pfx + conv_map.to_hu_conv + ";\n"
- to_hu_conv_sfx = to_hu_conv_sfx + conv_map.to_hu_conv_name
- else:
- to_hu_conv_sfx = to_hu_conv_sfx + ty_info.var_name + "_" + chr(idx + ord("a"))
- if conv_map.from_hu_conv is not None:
- from_hu_conv = from_hu_conv + conv_map.from_hu_conv[0].replace(ty_info.var_name + "_" + chr(idx + ord("a")), ty_info.var_name + "." + chr(idx + ord("a")))
- if conv_map.from_hu_conv[1] != "":
- from_hu_conv = from_hu_conv + "/*XXX: Need to call " + conv_map.from_hu_conv[1] + "*/"
- else:
- from_hu_conv = from_hu_conv + ty_info.var_name + "." + chr(idx + ord("a"))
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = ("long " + ty_info.var_name + "_ref = (long)&", ";"), ret_conv_name = ty_info.var_name + "_ref",
- to_hu_conv = to_hu_conv_pfx + to_hu_conv_sfx + ");", to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (from_hu_conv + ")", ""))
-
- # The manually-defined types - TxOut and Transaction
- assert ty_info.rust_obj == "LDKTransaction" or ty_info.rust_obj == "LDKTxOut"
- if ty_info.rust_obj == "LDKTransaction":
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = ("LDKTransaction *" + ty_info.var_name + "_copy = MALLOC(sizeof(LDKTransaction), \"LDKTransaction\");\n*" + ty_info.var_name + "_copy = ", ";\nlong " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_copy;"),
- ret_conv_name = ty_info.var_name + "_ref",
- to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " +ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
- to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = ("long " + ty_info.var_name + "_ref = (long)&", ";"), ret_conv_name = ty_info.var_name + "_ref",
- to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " +ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
- to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
- else:
- assert(not is_free)
- if ty_info.rust_obj in opaque_structs:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = opaque_arg_conv, arg_conv_name = "&" + ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None,
- to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = new " + ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
- to_hu_conv_name = ty_info.var_name + "_hu_conv",
- from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")")) # its a pointer, no conv needed
- elif ty_info.rust_obj in complex_enums:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + ";",
- arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None,
- to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = " + ty_info.java_hu_ty + ".constr_from_ptr(" + ty_info.var_name + ");",
- to_hu_conv_name = ty_info.var_name + "_hu_conv",
- from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")")) # its a pointer, no conv needed
- elif ty_info.rust_obj in trait_structs:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + ";",
- arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None, to_hu_conv = "TODO 2.5", to_hu_conv_name = None,
- from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr", "this.ptrs_to.add(" + ty_info.var_name + ")")) # its a pointer, no conv needed
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + ";",
- arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None, to_hu_conv = "TODO 3", to_hu_conv_name = None, from_hu_conv = None) # its a pointer, no conv needed
- elif ty_info.is_ptr:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = None, arg_conv_name = ty_info.var_name, arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None, 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 = ty_info.var_name, arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None, to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
- elif not print_void:
+ elif ty_info.var_name == "" and not print_void:
# We don't have a parameter name, and want one, just call it arg
if ty_info.rust_obj is not None:
assert(not is_free or ty_info.rust_obj not in opaque_structs)
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
arg_conv = None, arg_conv_name = "arg", arg_conv_cleanup = None,
ret_conv = None, ret_conv_name = None, to_hu_conv = "TODO 8", to_hu_conv_name = None, from_hu_conv = None)
+ elif ty_info.rust_obj is None:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = None, arg_conv_name = ty_info.var_name, arg_conv_cleanup = None,
+ ret_conv = None, ret_conv_name = None, to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
else:
- # We don't have a parameter name, and don't want one (cause we're returning)
- if ty_info.rust_obj is not None:
- if not ty_info.is_ptr:
- if ty_info.rust_obj in unitary_enums:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = ty_info.rust_obj + " ret_conv = " + ty_info.rust_obj + "_from_java(_env, ret);",
- arg_conv_name = "ret_conv", arg_conv_cleanup = None,
- ret_conv = ("jclass ret = " + ty_info.rust_obj + "_to_java(_env, ", ");"), ret_conv_name = "ret",
- to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
- if ty_info.rust_obj in complex_enums or ty_info.rust_obj in result_types:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = (ty_info.rust_obj + "* ret = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*ret = ", ";"),
- ret_conv_name = "(long)ret",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = " + ty_info.java_hu_ty + ".constr_from_ptr(ret);\nret_hu_conv.ptrs_to.add(this);",
- to_hu_conv_name = "ret_hu_conv", from_hu_conv = ("ret != null ? ret.ptr : 0", ""))
- if ty_info.rust_obj in opaque_structs:
- # If we're returning a newly-allocated struct, we don't want Rust to ever
- # free, instead relying on the Java GC to lose the ref. We undo this in
- # any _free function.
- # To avoid any issues, we first assert that the incoming object is non-ref.
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = (ty_info.rust_obj + " ret = ", ";"),
- ret_conv_name = "((long)ret.inner) | (ret.is_owned ? 1 : 0)",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = new " + ty_info.java_hu_ty + "(null, ret);",
- to_hu_conv_name = "ret_hu_conv", from_hu_conv = None)
- elif ty_info.rust_obj in trait_structs:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = (ty_info.rust_obj + "* ret = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*ret = ", ";"),
- ret_conv_name = "(long)ret",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = new " + ty_info.java_hu_ty + "(null, ret);\nret_hu_conv.ptrs_to.add(this);",
- to_hu_conv_name = "ret_hu_conv", from_hu_conv = ("ret.ptr", ""))
- elif ty_info.rust_obj in tuple_types:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = (ty_info.rust_obj + "* ret = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*ret = ", ";"),
- ret_conv_name = "(long)ret",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = new " + ty_info.java_hu_ty + "(null, ret);\nret_hu_conv.ptrs_to.add(this);",
- to_hu_conv_name = "ret_hu_conv", from_hu_conv = ("bindings." + ty_info.rust_obj.replace("LDK", "") + "_new(ret.a, ret.b)", ""))
+ if ty_info.var_name == "":
+ ty_info.var_name = "ret"
+ opaque_arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv;\n"
+ opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.inner = (void*)(" + ty_info.var_name + " & (~1));\n"
+ if holds_ref:
+ opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.is_owned = false;"
+ else:
+ opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.is_owned = (" + ty_info.var_name + " & 1) || (" + ty_info.var_name + " == 0);"
+ if not ty_info.is_ptr and not is_free and not ty_info.pass_by_ref and not holds_ref:
+ if (ty_info.java_hu_ty + "_clone") in clone_fns:
+ # TODO: This is a bit too naive, even with the checks above, we really need to know if rust wants a ref or not, not just if its pass as a ptr.
+ opaque_arg_conv = opaque_arg_conv + "\nif (" + ty_info.var_name + "_conv.inner != NULL)\n"
+ opaque_arg_conv = opaque_arg_conv + "\t" + ty_info.var_name + "_conv = " + ty_info.java_hu_ty + "_clone(&" + ty_info.var_name + "_conv);"
+ elif ty_info.passed_as_ptr:
+ opaque_arg_conv = opaque_arg_conv + "\n// Warning: we may need a move here but can't clone!"
+ if not ty_info.is_ptr:
+ if ty_info.rust_obj in unitary_enums:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = " + ty_info.rust_obj + "_from_java(_env, " + ty_info.var_name + ");",
+ arg_conv_name = ty_info.var_name + "_conv",
+ arg_conv_cleanup = None,
+ ret_conv = ("jclass " + ty_info.var_name + "_conv = " + ty_info.rust_obj + "_to_java(_env, ", ");"),
+ ret_conv_name = ty_info.var_name + "_conv", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
+ if ty_info.rust_obj in opaque_structs:
+ ret_conv_suf = ";\nCHECK((((long)" + ty_info.var_name + "_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.\n"
+ ret_conv_suf = ret_conv_suf + "CHECK((((long)&" + ty_info.var_name + "_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.\n"
+ if holds_ref:
+ ret_conv_suf = ret_conv_suf + "long " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_var.inner & ~1;"
else:
+ ret_conv_suf = ret_conv_suf + "long " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_var.inner;\n"
+ ret_conv_suf = ret_conv_suf + "if (" + ty_info.var_name + "_var.is_owned) {\n"
+ ret_conv_suf = ret_conv_suf + "\t" + ty_info.var_name + "_ref |= 1;\n"
+ ret_conv_suf = ret_conv_suf + "}"
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = opaque_arg_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = (ty_info.rust_obj + " " + ty_info.var_name + "_var = ", ret_conv_suf),
+ ret_conv_name = ty_info.var_name + "_ref",
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = new " + ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
+ to_hu_conv_name = ty_info.var_name + "_hu_conv",
+ from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")"))
+ base_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv = *(" + ty_info.rust_obj + "*)" + ty_info.var_name + ";";
+ if ty_info.rust_obj in trait_structs:
+ if not is_free:
+ base_conv = 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}"
+ else:
+ base_conv = base_conv + "\n" + "FREE((void*)" + ty_info.var_name + ");"
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = (ty_info.rust_obj + "* ret = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*ret = ", ";"),
+ ret_conv_name = "(long)ret",
+ to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = new " + ty_info.java_hu_ty + "(null, ret);\nret_hu_conv.ptrs_to.add(this);",
+ to_hu_conv_name = "ret_hu_conv",
+ from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr", "this.ptrs_to.add(" + ty_info.var_name + ")"))
+ if ty_info.rust_obj != "LDKu8slice" and ty_info.rust_obj != "LDKTransaction":
+ # Don't bother free'ing slices passed in - Rust doesn't auto-free the
+ # underlying unlike Vecs, and it gives Java more freedom.
+ base_conv = base_conv + "\nFREE((void*)" + ty_info.var_name + ");";
+ if ty_info.rust_obj in complex_enums:
+ ret_conv = ("long " + ty_info.var_name + "_ref = (long)&", ";")
+ if not holds_ref:
+ ret_conv = (ty_info.rust_obj + " *" + ty_info.var_name + "_copy = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n", "")
+ if not ty_info.passed_as_ptr:
+ # We use passed_as_ptr as a flag to detect if we're copying a Vec.
+ if (ty_info.java_hu_ty + "_clone") in clone_fns:
+ ret_conv = (ret_conv[0] + "*" + ty_info.var_name + "_copy = " + ty_info.java_hu_ty + "_clone(&", ");\n")
+ else:
+ ret_conv = (ret_conv[0] + "*" + ty_info.var_name + "_copy = ", "; // XXX: We likely need to clone here, but no _clone fn is available!\n")
+ else:
+ ret_conv = (ret_conv[0] + "*" + ty_info.var_name + "_copy = ", ";\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "long " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_copy;")
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ret_conv, ret_conv_name = ty_info.var_name + "_ref",
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = " + ty_info.java_hu_ty + ".constr_from_ptr(" + ty_info.var_name + ");\n" + ty_info.var_name + "_hu_conv.ptrs_to.add(this);",
+ to_hu_conv_name = ty_info.var_name + "_hu_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
+ if ty_info.rust_obj in result_types:
+ assert not ty_info.is_ptr and not holds_ref # Otherwise we shouldn't be MALLOC'ing
+ ret_conv = (ty_info.rust_obj + "* " + ty_info.var_name + "_conv = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*" + ty_info.var_name + "_conv = ", ";")
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ret_conv, ret_conv_name = "(long)" + ty_info.var_name + "_conv",
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = " + ty_info.java_hu_ty + ".constr_from_ptr(" + ty_info.var_name + ");\n" + ty_info.var_name + "_hu_conv.ptrs_to.add(this);",
+ to_hu_conv_name = ty_info.var_name + "_hu_conv", from_hu_conv = (ty_info.var_name + " != null ? " + ty_info.var_name + ".ptr : 0", ""))
+ if ty_info.rust_obj in tuple_types:
+ from_hu_conv = "bindings." + tuple_types[ty_info.rust_obj][1].replace("LDK", "") + "_new("
+ to_hu_conv_pfx = ""
+ to_hu_conv_sfx = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " + ty_info.java_hu_ty + "("
+ for idx, conv in enumerate(tuple_types[ty_info.rust_obj][0]):
+ if idx != 0:
+ to_hu_conv_sfx = to_hu_conv_sfx + ", "
+ from_hu_conv = from_hu_conv + ", "
+ conv.var_name = ty_info.var_name + "_" + chr(idx + ord("a"))
+ conv_map = map_type_with_info(conv, False, None, is_free, holds_ref)
+ to_hu_conv_pfx = to_hu_conv_pfx + conv.java_ty + " " + ty_info.var_name + "_" + chr(idx + ord("a")) + " = " + "bindings." + tuple_types[ty_info.rust_obj][1] + "_get_" + chr(idx + ord("a")) + "(" + ty_info.var_name + ");\n"
+ if conv_map.to_hu_conv is not None:
+ to_hu_conv_pfx = to_hu_conv_pfx + conv_map.to_hu_conv + ";\n"
+ to_hu_conv_sfx = to_hu_conv_sfx + conv_map.to_hu_conv_name
+ else:
+ to_hu_conv_sfx = to_hu_conv_sfx + ty_info.var_name + "_" + chr(idx + ord("a"))
+ if conv_map.from_hu_conv is not None:
+ from_hu_conv = from_hu_conv + conv_map.from_hu_conv[0].replace(ty_info.var_name + "_" + chr(idx + ord("a")), ty_info.var_name + "." + chr(idx + ord("a")))
+ if conv_map.from_hu_conv[1] != "":
+ from_hu_conv = from_hu_conv + "/*XXX: " + conv_map.from_hu_conv[1] + "*/"
+ else:
+ from_hu_conv = from_hu_conv + ty_info.var_name + "." + chr(idx + ord("a"))
+
+ if not ty_info.is_ptr and not holds_ref:
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = (ty_info.rust_obj + "* ret = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*ret = ", ";"),
- ret_conv_name = "(long)ret",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = new " + ty_info.java_hu_ty + "(null, ret);\nret_hu_conv.ptrs_to.add(this);",
- to_hu_conv_name = "ret_hu_conv", from_hu_conv = None)
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+
+ ret_conv = (ty_info.rust_obj + "* " + ty_info.var_name + "_ref = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*" + ty_info.var_name + "_ref = ", ";"),
+ ret_conv_name = "(long)" + ty_info.var_name + "_ref",
+ to_hu_conv = to_hu_conv_pfx + to_hu_conv_sfx + ");", to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (from_hu_conv + ")", ""))
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("long " + ty_info.var_name + "_ref = (long)&", ";"), ret_conv_name = ty_info.var_name + "_ref",
+ to_hu_conv = to_hu_conv_pfx + to_hu_conv_sfx + ");", to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (from_hu_conv + ")", ""))
+
+ # The manually-defined types - TxOut and Transaction
+ assert ty_info.rust_obj == "LDKTransaction" or ty_info.rust_obj == "LDKTxOut"
+ if ty_info.rust_obj == "LDKTransaction":
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("LDKTransaction *" + ty_info.var_name + "_copy = MALLOC(sizeof(LDKTransaction), \"LDKTransaction\");\n*" + ty_info.var_name + "_copy = ", ";\nlong " + ty_info.var_name + "_ref = (long)" + ty_info.var_name + "_copy;"),
+ ret_conv_name = ty_info.var_name + "_ref",
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " +ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
+ to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
+ elif ty_info.rust_obj == "LDKTxOut":
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("long " + ty_info.var_name + "_ref = (long)&", ";"), ret_conv_name = ty_info.var_name + "_ref",
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " +ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
+ to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
+ elif ty_info.is_ptr:
+ assert(not is_free)
+ if ty_info.rust_obj in opaque_structs:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = opaque_arg_conv, arg_conv_name = "&" + ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("long ret_" + ty_info.var_name + " = (long)", ";"), ret_conv_name = "ret_" + ty_info.var_name,
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = new " + ty_info.java_hu_ty + "(null, " + ty_info.var_name + ");",
+ to_hu_conv_name = ty_info.var_name + "_hu_conv",
+ from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")"))
+ elif ty_info.rust_obj in complex_enums:
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + ";",
+ arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("long ret_" + ty_info.var_name + " = (long)", ";"), ret_conv_name = "ret_" + ty_info.var_name,
+ to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_hu_conv = " + ty_info.java_hu_ty + ".constr_from_ptr(" + ty_info.var_name + ");",
+ to_hu_conv_name = ty_info.var_name + "_hu_conv",
+ from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")"))
elif ty_info.rust_obj in trait_structs:
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = ("long ret = (long)", ";"), ret_conv_name = "ret",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
+ arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + ";",
+ arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("long ret_" + ty_info.var_name + " = (long)", ";"), ret_conv_name = "ret_" + ty_info.var_name,
to_hu_conv = ty_info.java_hu_ty + " ret_hu_conv = new " + ty_info.java_hu_ty + "(null, ret);\nret_hu_conv.ptrs_to.add(this);",
- to_hu_conv_name = "ret_hu_conv", from_hu_conv = None)
- else:
- return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- ret_conv = ("long ret = (long)", ";"), ret_conv_name = "ret",
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- to_hu_conv = "TODO c", to_hu_conv_name = None, from_hu_conv = None)
- else:
+ to_hu_conv_name = "ret_hu_conv",
+ from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr", "this.ptrs_to.add(" + ty_info.var_name + ")"))
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
- arg_conv = None, arg_conv_name = None, arg_conv_cleanup = None,
- ret_conv = None, ret_conv_name = None,
- to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
+ arg_conv = ty_info.rust_obj + "* " + ty_info.var_name + "_conv = (" + ty_info.rust_obj + "*)" + ty_info.var_name + ";",
+ arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
+ ret_conv = ("long ret_" + ty_info.var_name + " = (long)", ";"), ret_conv_name = "ret_" + ty_info.var_name,
+ to_hu_conv = "TODO 3", to_hu_conv_name = None, from_hu_conv = None) # its a pointer, no conv needed
+ assert False # We should have handled every case by now.
def map_fn(line, re_match, ret_arr_len, c_call_string):
out_java.write("\t// " + line)
arg_conv_info.print_name()
if arg_conv_info.arg_name == "this_ptr" or arg_conv_info.arg_name == "this_arg":
takes_self = True
- if arg_conv_info.passed_as_ptr and not arg_conv_info.rust_obj in opaque_structs:
- if not arg_conv_info.rust_obj in trait_structs and not arg_conv_info.rust_obj in unitary_enums:
- args_known = False
if arg_conv_info.arg_conv is not None and "Warning" in arg_conv_info.arg_conv:
if arg_conv_info.rust_obj in constructor_fns:
assert not is_free
out_c.write("\tatomic_size_t refcnt;\n")
out_c.write("\tJavaVM *vm;\n")
out_c.write("\tjweak o;\n")
+ field_var_convs = []
for var_line in field_var_lines:
if var_line.group(1) in trait_structs:
out_c.write("\t" + var_line.group(1) + "_JCalls* " + var_line.group(2) + ";\n")
+ field_var_convs.append(None)
+ else:
+ field_var_convs.append(map_type(var_line.group(1) + " " + var_line.group(2), False, None, False, False))
for fn_line in trait_fn_lines:
if fn_line.group(2) != "free" and fn_line.group(2) != "clone":
out_c.write("\tjmethodID " + fn_line.group(2) + "_meth;\n")
out_java_trait.write("\tfinal bindings." + struct_name + " bindings_instance;\n")
out_java_trait.write("\t" + struct_name.replace("LDK", "") + "(Object _dummy, long ptr) { super(ptr); bindings_instance = null; }\n")
out_java_trait.write("\tprivate " + struct_name.replace("LDK", "") + "(bindings." + struct_name + " arg")
- for var_line in field_var_lines:
+ for idx, var_line in enumerate(field_var_lines):
if var_line.group(1) in trait_structs:
out_java_trait.write(", bindings." + var_line.group(1) + " " + var_line.group(2))
+ else:
+ out_java_trait.write(", " + field_var_convs[idx].java_hu_ty + " " + var_line.group(2))
out_java_trait.write(") {\n")
out_java_trait.write("\t\tsuper(bindings." + struct_name + "_new(arg")
- for var_line in field_var_lines:
+ for idx, var_line in enumerate(field_var_lines):
if var_line.group(1) in trait_structs:
out_java_trait.write(", " + var_line.group(2))
+ elif field_var_convs[idx].from_hu_conv is not None:
+ out_java_trait.write(", " + field_var_convs[idx].from_hu_conv[0])
+ else:
+ out_java_trait.write(", " + var_line.group(2))
out_java_trait.write("));\n")
out_java_trait.write("\t\tthis.ptrs_to.add(arg);\n")
+ for idx, var_line in enumerate(field_var_lines):
+ if var_line.group(1) in trait_structs:
+ out_java_trait.write("\t\tthis.ptrs_to.add(" + var_line.group(2) + ");\n")
+ elif field_var_convs[idx].from_hu_conv is not None and field_var_convs[idx].from_hu_conv[1] != "":
+ out_java_trait.write("\t\t" + field_var_convs[idx].from_hu_conv[1] + ";\n")
out_java_trait.write("\t\tthis.bindings_instance = arg;\n")
out_java_trait.write("\t}\n")
out_java_trait.write("\t@Override @SuppressWarnings(\"deprecation\")\n")
out_java_trait.write("\t}\n\n")
java_trait_constr = "\tpublic " + struct_name.replace("LDK", "") + "(" + struct_name.replace("LDK", "") + "Interface arg"
- for var_line in field_var_lines:
+ for idx, var_line in enumerate(field_var_lines):
if var_line.group(1) in trait_structs:
# Ideally we'd be able to take any instance of the interface, but our C code can only represent
# Java-implemented version, so we require users pass a Java implementation here :/
java_trait_constr = java_trait_constr + ", " + var_line.group(1).replace("LDK", "") + "." + var_line.group(1).replace("LDK", "") + "Interface " + var_line.group(2)
+ else:
+ java_trait_constr = java_trait_constr + ", " + field_var_convs[idx].java_hu_ty + " " + var_line.group(2)
java_trait_constr = java_trait_constr + ") {\n\t\tthis(new bindings." + struct_name + "() {\n"
out_java_trait.write("\tpublic static interface " + struct_name.replace("LDK", "") + "Interface {\n")
out_java.write("\tpublic interface " + struct_name + " {\n")
out_c.write("\tjobject obj = (*_env)->NewLocalRef(_env, j_calls->o);\n\tCHECK(obj != NULL);\n")
if ret_ty_info.c_ty.endswith("Array"):
- out_c.write("\t" + ret_ty_info.c_ty + " ret = (*_env)->CallObjectMethod(_env, obj, j_calls->" + fn_line.group(2) + "_meth")
+ out_c.write("\t" + ret_ty_info.c_ty + " arg = (*_env)->CallObjectMethod(_env, obj, j_calls->" + fn_line.group(2) + "_meth")
elif not ret_ty_info.passed_as_ptr:
out_c.write("\treturn (*_env)->Call" + ret_ty_info.java_ty.title() + "Method(_env, obj, j_calls->" + fn_line.group(2) + "_meth")
else:
java_trait_constr = java_trait_constr + arg_info.arg_name
out_c.write(");\n");
if ret_ty_info.arg_conv is not None:
- out_c.write("\t" + ret_ty_info.arg_conv.replace("\n", "\n\t").replace("arg", "ret") + "\n\treturn " + ret_ty_info.arg_conv_name.replace("arg", "ret") + ";\n")
+ out_c.write("\t" + ret_ty_info.arg_conv.replace("\n", "\n\t") + "\n\treturn " + ret_ty_info.arg_conv_name + ";\n")
- if ret_ty_info.passed_as_ptr:
- out_c.write("\t" + fn_line.group(1).strip() + " res = *ret;\n")
- out_c.write("\tFREE(ret);\n")
- out_c.write("\treturn res;\n")
out_c.write("}\n")
java_trait_constr = java_trait_constr + ");\n"
if ret_ty_info.java_ty != "void":
if ret_ty_info.from_hu_conv is not None:
java_trait_constr = java_trait_constr + "\t\t\t\t" + ret_ty_info.java_ty + " result = " + ret_ty_info.from_hu_conv[0] + ";\n"
if ret_ty_info.from_hu_conv[1] != "":
- java_trait_constr = java_trait_constr + "\t\t\t\t" + ret_ty_info.from_hu_conv[1] + "\n"
+ java_trait_constr = java_trait_constr + "\t\t\t\t//TODO: May need to call: " + ret_ty_info.from_hu_conv[1] + ";\n"
if is_common_base_ext(ret_ty_info.rust_obj):
java_trait_constr = java_trait_constr + "\t\t\t\tret.ptr = 0;\n"
java_trait_constr = java_trait_constr + "\t\t\t\treturn result;\n"
for var_line in field_var_lines:
if var_line.group(1) in trait_structs:
java_trait_constr = java_trait_constr + ", new " + var_line.group(2) + "(" + var_line.group(2) + ").bindings_instance"
+ else:
+ java_trait_constr = java_trait_constr + ", " + var_line.group(2)
out_java_trait.write("\t}\n")
out_java_trait.write(java_trait_constr + ");\n\t}\n")
out_java.write("\tpublic static native long " + struct_name + "_new(" + struct_name + " impl")
out_c.write("static inline " + struct_name + " " + struct_name + "_init (JNIEnv * env, jclass _a, jobject o")
- for var_line in field_var_lines:
+ for idx, var_line in enumerate(field_var_lines):
if var_line.group(1) in trait_structs:
out_java.write(", " + var_line.group(1) + " " + var_line.group(2))
out_c.write(", jobject " + var_line.group(2))
+ else:
+ out_java.write(", " + field_var_convs[idx].java_ty + " " + var_line.group(2))
+ out_c.write(", " + field_var_convs[idx].c_ty + " " + var_line.group(2))
out_java.write(");\n")
out_c.write(") {\n")
if fn_line.group(2) != "free" and fn_line.group(2) != "clone":
out_c.write("\tcalls->" + fn_line.group(2) + "_meth = (*env)->GetMethodID(env, c, \"" + fn_line.group(2) + "\", \"" + java_meth_descr + "\");\n")
out_c.write("\tCHECK(calls->" + fn_line.group(2) + "_meth != NULL);\n")
+ for idx, var_line in enumerate(field_var_lines):
+ if field_var_convs[idx] is not None and field_var_convs[idx].arg_conv is not None:
+ out_c.write("\n\t" + field_var_convs[idx].arg_conv.replace("\n", "\n\t") +"\n")
out_c.write("\n\t" + struct_name + " ret = {\n")
out_c.write("\t\t.this_arg = (void*) calls,\n")
for fn_line in trait_fn_lines:
else:
clone_fns.add(struct_name + "_clone")
out_c.write("\t\t.clone = " + struct_name + "_JCalls_clone,\n")
- for var_line in field_var_lines:
+ for idx, var_line in enumerate(field_var_lines):
if var_line.group(1) in trait_structs:
out_c.write("\t\t." + var_line.group(2) + " = " + var_line.group(1) + "_init(env, _a, " + var_line.group(2) + "),\n")
+ elif field_var_convs[idx].arg_conv_name is not None:
+ out_c.write("\t\t." + var_line.group(2) + " = " + field_var_convs[idx].arg_conv_name + ",\n")
+ out_c.write("\t\t.set_" + var_line.group(2) + " = NULL,\n")
+ else:
+ out_c.write("\t\t." + var_line.group(2) + " = " + var_line.group(2) + ",\n")
+ out_c.write("\t\t.set_" + var_line.group(2) + " = NULL,\n")
out_c.write("\t};\n")
for var_line in field_var_lines:
if var_line.group(1) in trait_structs:
out_c.write("}\n")
out_c.write("JNIEXPORT long JNICALL Java_org_ldk_impl_bindings_" + struct_name.replace("_", "_1") + "_1new (JNIEnv * env, jclass _a, jobject o")
- for var_line in field_var_lines:
+ for idx, var_line in enumerate(field_var_lines):
if var_line.group(1) in trait_structs:
out_c.write(", jobject " + var_line.group(2))
+ else:
+ out_c.write(", " + field_var_convs[idx].c_ty + " " + var_line.group(2))
out_c.write(") {\n")
out_c.write("\t" + struct_name + " *res_ptr = MALLOC(sizeof(" + struct_name + "), \"" + struct_name + "\");\n")
out_c.write("\t*res_ptr = " + struct_name + "_init(env, _a, o")
for var_line in field_var_lines:
- if var_line.group(1) in trait_structs:
- out_c.write(", " + var_line.group(2))
+ out_c.write(", " + var_line.group(2))
out_c.write(");\n")
out_c.write("\treturn (long)res_ptr;\n")
out_c.write("}\n")
if fn_line.group(2) != "free" and fn_line.group(2) != "clone" and fn_line.group(2) != "eq" and not is_log:
dummy_line = fn_line.group(1) + struct_name.replace("LDK", "") + "_" + fn_line.group(2) + " " + struct_name + "* this_arg" + fn_line.group(4) + "\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(2) + ")(this_arg_conv->this_arg")
+ for idx, var_line in enumerate(field_var_lines):
+ if var_line.group(1) not in trait_structs:
+ out_c.write(var_line.group(1) + " " + struct_name + "_set_get_" + var_line.group(2) + "(" + struct_name + "* this_arg) {\n")
+ out_c.write("\tif (this_arg->set_" + var_line.group(2) + " != NULL)\n")
+ out_c.write("\t\tthis_arg->set_" + var_line.group(2) + "(this_arg);\n")
+ out_c.write("\treturn this_arg->" + var_line.group(2) + ";\n")
+ out_c.write("}\n")
+ dummy_line = var_line.group(1) + " " + struct_name.replace("LDK", "") + "_get_" + var_line.group(2) + " " + struct_name + "* this_arg" + fn_line.group(4) + "\n"
+ map_fn(dummy_line, re.compile("([A-Za-z_0-9]*) *([A-Za-z_0-9]*) *(.*)").match(dummy_line), None, struct_name + "_set_get_" + var_line.group(2) + "(this_arg_conv")
out_c.write("""#include \"org_ldk_impl_bindings.h\"
#include <rust_types.h>
#include <stdatomic.h>
""")
- if sys.argv[4] == "false":
+ if sys.argv[5] == "false":
out_c.write("#define MALLOC(a, _) malloc(a)\n")
- out_c.write("#define FREE(p) if ((p) > 1024) { free(p); }\n")
+ out_c.write("#define FREE(p) if ((long)(p) > 1024) { free(p); }\n")
out_c.write("#define DO_ASSERT(a) (void)(a)\n")
out_c.write("#define CHECK(a)\n")
else:
while (it->ptr != ptr) {
p = it; it = it->next;
if (it == NULL) {
- fprintf(stderr, "Tried to free unknown pointer %p!\\n", ptr);
+ fprintf(stderr, "Tried to free unknown pointer %p at:\\n", ptr);
+ void* bt[BT_MAX];
+ int bt_len = backtrace(bt, BT_MAX);
+ backtrace_symbols_fd(bt, bt_len, STDERR_FILENO);
+ fprintf(stderr, "\\n\\n");
+ DO_ASSERT(mtx_unlock(&allocation_mtx) == thrd_success);
return; // addrsan should catch malloc-unknown and print more info than we have
}
}
public static native long bytes_to_u8_vec(byte[] bytes);
public static native long new_txpointer_copy_data(byte[] txdata);
public static native void txpointer_free(long ptr);
+ public static native byte[] txpointer_get_buffer(long ptr);
public static native long vec_slice_len(long vec);
public static native long new_empty_slice_vec();
(*_env)->GetByteArrayRegion (_env, bytes, 0, vec->datalen, vec->data);
return (long)vec;
}
+JNIEXPORT jbyteArray JNICALL Java_org_ldk_impl_bindings_txpointer_1get_1buffer (JNIEnv * env, jclass _b, jlong ptr) {
+ LDKTransaction *txdata = (LDKTransaction*)ptr;
+ LDKu8slice slice;
+ slice.data = txdata->data;
+ slice.datalen = txdata->datalen;
+ return Java_org_ldk_impl_bindings_get_1u8_1slice_1bytes(env, _b, (long)&slice);
+}
JNIEXPORT long JNICALL Java_org_ldk_impl_bindings_new_1txpointer_1copy_1data (JNIEnv * env, jclass _b, jbyteArray bytes) {
LDKTransaction *txdata = (LDKTransaction*)MALLOC(sizeof(LDKTransaction), "LDKTransaction");
txdata->datalen = (*env)->GetArrayLength(env, bytes);
assert(line_indicates_trait_regex.match(" void *(*clone)(const void *this_arg);"))
line_field_var_regex = re.compile("^ ([A-Za-z_0-9]*) ([A-Za-z_0-9]*);$")
assert(line_field_var_regex.match(" LDKMessageSendEventsProvider MessageSendEventsProvider;"))
+ assert(line_field_var_regex.match(" LDKChannelPublicKeys pubkeys;"))
struct_name_regex = re.compile("^typedef (struct|enum|union) (MUST_USE_STRUCT )?(LDK[A-Za-z_0-9]*) {$")
assert(struct_name_regex.match("typedef struct LDKCVecTempl_u8 {"))
assert(struct_name_regex.match("typedef enum LDKNetwork {"))
out_java_struct.write("\tTransaction(java.lang.Object _dummy, long ptr) { super(ptr); }\n")
out_java_struct.write("\tpublic Transaction(byte[] data) { super(bindings.new_txpointer_copy_data(data)); }\n")
out_java_struct.write("\t@Override public void finalize() throws Throwable { super.finalize(); bindings.txpointer_free(ptr); }\n")
+ out_java_struct.write("\tpublic byte[] get_contents() { return bindings.txpointer_get_buffer(ptr); }\n")
# TODO: Transaction body
out_java_struct.write("}")
else:
for idx, ty_info in enumerate(tuple_types[alias_match.group(1)][0]):
e = chr(ord('a') + idx)
out_java.write("\tpublic static native " + ty_info.java_ty + " " + alias_match.group(2) + "_get_" + e + "(long ptr);\n")
- # XXX: Write C method!
+ out_c.write("JNIEXPORT " + ty_info.c_ty + " JNICALL Java_org_ldk_impl_bindings_" + alias_match.group(2).replace("_", "_1") + "_1get_1" + e + "(JNIEnv *_env, jclass _b, jlong ptr) {\n")
+ out_c.write("\t" + alias_match.group(1) + " *tuple = (" + alias_match.group(1) + "*)ptr;\n")
+ conv_info = map_type_with_info(ty_info, False, None, False, True)
+ if conv_info.ret_conv is not None:
+ out_c.write("\t" + conv_info.ret_conv[0].replace("\n", "\n\t") + "tuple->" + e + conv_info.ret_conv[1].replace("\n", "\n\t") + "\n")
+ out_c.write("\treturn " + conv_info.ret_conv_name + ";\n")
+ else:
+ out_c.write("\treturn tuple->" + e + ";\n")
+ out_c.write("}\n")
elif alias_match.group(1) in result_templ_structs:
result_types.add(alias_match.group(2))
human_ty = alias_match.group(2).replace("LDKCResult", "Result")