+ arg_conv = arg_conv, arg_conv_name = arr_name + "_ref", arg_conv_cleanup = arg_conv_cleanup,
+ ret_conv = ret_conv, ret_conv_name = arr_name + "_arr", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
+ else:
+ assert not arr_len.isdigit() # fixed length arrays not implemented
+ assert ty_info.java_ty[len(ty_info.java_ty) - 2:] == "[]"
+ 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
+ #XXX: We'd really prefer to only ever set to False, avoiding lots of clone, but need smarter free logic
+ #if ty_info.is_ptr or holds_ref:
+ # ty_info.subty.requires_clone = False
+ ty_info.subty.requires_clone = not ty_info.is_ptr or not holds_ref
+ subty = map_type_with_info(ty_info.subty, False, None, is_free, holds_ref)
+ if arr_name == "":
+ arr_name = "arg"
+ arg_conv = ty_info.rust_obj + " " + arr_name + "_constr;\n"
+ arg_conv = arg_conv + arr_name + "_constr." + arr_len + " = " + consts.get_native_arr_len_call[0] + arr_name + consts.get_native_arr_len_call[1] + ";\n"
+ arg_conv = arg_conv + "if (" + arr_name + "_constr." + arr_len + " > 0)\n"
+ if subty.rust_obj is None:
+ szof = subty.c_ty
+ else:
+ szof = subty.rust_obj
+ arg_conv = arg_conv + "\t" + arr_name + "_constr." + ty_info.arr_access + " = MALLOC(" + arr_name + "_constr." + arr_len + " * sizeof(" + szof + "), \"" + ty_info.rust_obj + " Elements\");\n"
+ arg_conv = arg_conv + "else\n"
+ arg_conv = arg_conv + "\t" + arr_name + "_constr." + ty_info.arr_access + " = NULL;\n"
+ get_arr = consts.get_native_arr_contents(arr_name, "NO_DEST", arr_name + "_constr." + arr_len, ty_info, False)
+ if get_arr != None:
+ arg_conv = arg_conv + subty.c_ty + "* " + arr_name + "_vals = " + get_arr + ";\n"
+ arg_conv = arg_conv + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_constr." + arr_len + "; " + idxc + "++) {\n"
+ if get_arr != None:
+ arg_conv = arg_conv + "\t" + subty.c_ty + " " + conv_name + " = " + arr_name + "_vals[" + idxc + "];"
+ if subty.arg_conv is not None:
+ arg_conv = arg_conv + "\n\t" + subty.arg_conv.replace("\n", "\n\t")
+ else:
+ arg_conv = arg_conv + "\t" + subty.c_ty + " " + conv_name + " = " + consts.get_native_arr_elem(arr_name, idxc, ty_info) + ";\n"
+ arg_conv = arg_conv + "\t" + subty.arg_conv.replace("\n", "\n\t")
+ arg_conv = arg_conv + "\n\t" + arr_name + "_constr." + ty_info.arr_access + "[" + idxc + "] = " + subty.arg_conv_name + ";\n}"
+ if get_arr != None:
+ cleanup = consts.cleanup_native_arr_ref_contents(arr_name, arr_name + "_vals", arr_name + "_constr." + arr_len, ty_info)
+ if cleanup is not None:
+ arg_conv = arg_conv + "\n" + cleanup + ";"
+ if ty_info.is_ptr:
+ arg_conv_name = "&" + arr_name + "_constr"
+ else:
+ arg_conv_name = arr_name + "_constr"
+ arg_conv_cleanup = None
+ if ty_info.is_ptr:
+ arg_conv_cleanup = "FREE(" + arr_name + "_constr." + ty_info.arr_access + ");"
+
+ if arr_name == "arg":
+ arr_name = "ret"
+ ret_conv = (ty_info.rust_obj + " " + arr_name + "_var = ", "")
+ if subty.ret_conv is None:
+ ret_conv = ("DUMMY", "DUMMY")
+ elif not ty_info.java_ty[:len(ty_info.java_ty) - 2].endswith("[]"):
+ ret_conv = (ret_conv[0], ";\n" + ty_info.c_ty + " " + arr_name + "_arr = " + consts.create_native_arr_call(arr_name + "_var." + arr_len, ty_info) + ";\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + subty.c_ty + " *" + arr_name + "_arr_ptr = " + consts.get_native_arr_ptr_call[0] + arr_name + "_arr" + consts.get_native_arr_ptr_call[1] + ";\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_var." + arr_len + "; " + idxc + "++) {\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "\t" + subty.ret_conv[0].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + arr_name + "_var." + ty_info.arr_access + "[" + idxc + "]" + subty.ret_conv[1].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + "\n\t" + arr_name + "_arr_ptr[" + idxc + "] = " + subty.ret_conv_name + ";\n}")
+ cleanup = consts.release_native_arr_ptr_call(arr_name + "_arr", arr_name + "_arr_ptr")
+ if cleanup is not None:
+ ret_conv = (ret_conv[0], ret_conv[1] + "\n" + cleanup + ";")
+ else:
+ assert ty_info.java_fn_ty_arg.startswith("[")
+ clz_var = ty_info.java_fn_ty_arg[1:].replace("[", "arr_of_")
+ c_array_class_caches.add(clz_var)
+ ret_conv = (ret_conv[0], ";\n" + ty_info.c_ty + " " + arr_name + "_arr = (*env)->NewObjectArray(env, " + arr_name + "_var." + arr_len + ", " + clz_var + "_clz, NULL);\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_var." + arr_len + "; " + idxc + "++) {\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "\t" + subty.ret_conv[0].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + arr_name + "_var." + ty_info.arr_access + "[" + idxc + "]" + subty.ret_conv[1].replace("\n", "\n\t"))
+ ret_conv = (ret_conv[0], ret_conv[1] + "\n\t(*env)->SetObjectArrayElement(env, " + arr_name + "_arr, " + idxc + ", " + subty.ret_conv_name + ");\n")
+ ret_conv = (ret_conv[0], ret_conv[1] + "}")
+ if not holds_ref:
+ # XXX: The commented if's are a bit smarter freeing, but we need to be a nudge smarter still
+ # Note that we don't drop the full vec here - we're passing ownership to java (or have cloned) or free'd by now!
+ ret_conv = (ret_conv[0], ret_conv[1] + "\nFREE(" + arr_name + "_var." + ty_info.arr_access + ");")
+ #if subty.rust_obj is not None and subty.rust_obj in opaque_structs:
+ # ret_conv = (ret_conv[0], ret_conv[1] + "\nFREE(" + arr_name + "_var." + ty_info.arr_access + ");")
+ #else:
+ # ret_conv = (ret_conv[0], ret_conv[1] + "\n" + ty_info.rust_obj.replace("LDK", "") + "_free(" + arr_name + "_var);")
+
+ to_hu_conv = None
+ to_hu_conv_name = None
+ if subty.to_hu_conv is not None:
+ to_hu_conv = ty_info.java_hu_ty + " " + conv_name + "_arr = new " + ty_info.subty.java_hu_ty.split("<")[0] + "[" + arr_name + ".length];\n"
+ to_hu_conv = to_hu_conv + "for (int " + idxc + " = 0; " + idxc + " < " + arr_name + ".length; " + idxc + "++) {\n"
+ to_hu_conv = to_hu_conv + "\t" + subty.java_ty + " " + conv_name + " = " + arr_name + "[" + idxc + "];\n"
+ to_hu_conv = to_hu_conv + "\t" + subty.to_hu_conv.replace("\n", "\n\t") + "\n"
+ to_hu_conv = to_hu_conv + "\t" + conv_name + "_arr[" + idxc + "] = " + subty.to_hu_conv_name + ";\n}"
+ to_hu_conv_name = conv_name + "_arr"
+ from_hu_conv = None
+ if subty.from_hu_conv is not None:
+ if subty.java_ty == "long" and subty.java_hu_ty != "long":
+ from_hu_conv = ("Arrays.stream(" + arr_name + ").mapToLong(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
+ elif subty.java_ty == "long":
+ from_hu_conv = ("Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
+ else:
+ from_hu_conv = ("(" + ty_info.java_ty + ")Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
+
+ return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
+ 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 ty_info.arr_access is None: