@@ -157,20 +157,29 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
157157 to_hu_conv = None
158158 to_hu_conv_name = None
159159 if subty .to_hu_conv is not None :
160- to_hu_conv = ty_info .java_hu_ty + " " + conv_name + "_arr = new " + ty_info .subty .java_hu_ty .split ("<" )[0 ] + "[" + arr_name + ".length];\n "
161- to_hu_conv = to_hu_conv + "for (int " + idxc + " = 0; " + idxc + " < " + arr_name + ".length; " + idxc + "++) {\n "
162- to_hu_conv = to_hu_conv + "\t " + subty .java_ty + " " + conv_name + " = " + arr_name + "[" + idxc + "];\n "
163- to_hu_conv = to_hu_conv + "\t " + subty .to_hu_conv .replace ("\n " , "\n \t " ) + "\n "
164- to_hu_conv = to_hu_conv + "\t " + conv_name + "_arr[" + idxc + "] = " + subty .to_hu_conv_name + ";\n }"
160+ base_ty = ty_info .subty .java_hu_ty .split ("[" )[0 ].split ("<" )[0 ]
161+ to_hu_conv = ty_info .java_hu_ty + " " + conv_name + "_arr = new " + base_ty + "[" + arr_name + ".length]"
162+ if "[" in ty_info .subty .java_hu_ty .split ("<" )[0 ]:
163+ # Do a bit of a dance to move any excess [] to the end
164+ to_hu_conv += "[" + ty_info .subty .java_hu_ty .split ("<" )[0 ].split ("[" )[1 ]
165+ to_hu_conv += ";\n for (int " + idxc + " = 0; " + idxc + " < " + arr_name + ".length; " + idxc + "++) {\n "
166+ to_hu_conv += "\t " + subty .java_ty + " " + conv_name + " = " + arr_name + "[" + idxc + "];\n "
167+ to_hu_conv += "\t " + subty .to_hu_conv .replace ("\n " , "\n \t " ) + "\n "
168+ to_hu_conv += "\t " + conv_name + "_arr[" + idxc + "] = " + subty .to_hu_conv_name + ";\n }"
165169 to_hu_conv_name = conv_name + "_arr"
166170 from_hu_conv = None
167171 if subty .from_hu_conv is not None :
172+ hu_conv_b = ""
173+ if subty .from_hu_conv [1 ] != "" :
174+ hu_conv_b = "for (" + subty .java_hu_ty + " " + conv_name + ": " + arr_name + ") { " + subty .from_hu_conv [1 ] + "; }"
168175 if subty .java_ty == "long" and subty .java_hu_ty != "long" :
169- from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").mapToLong(" + conv_name + " -> " + subty .from_hu_conv [0 ] + ").toArray() : null" , "/* TODO 2 " + subty .java_hu_ty + " */" )
176+ from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").mapToLong(" + conv_name + " -> " + subty .from_hu_conv [0 ] + ").toArray() : null" ,
177+ hu_conv_b )
170178 elif subty .java_ty == "long" :
171179 from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty .from_hu_conv [0 ] + ").toArray() : null" , "/* TODO 2 " + subty .java_hu_ty + " */" )
172180 else :
173- from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty .from_hu_conv [0 ] + ").toArray(" + ty_info .java_ty + "::new) : null" , "/* TODO 2 " + subty .java_hu_ty + " */" )
181+ from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty .from_hu_conv [0 ] + ").toArray(" + ty_info .java_ty + "::new) : null" ,
182+ hu_conv_b )
174183
175184 return ConvInfo (ty_info = ty_info , arg_name = ty_info .var_name ,
176185 arg_conv = arg_conv , arg_conv_name = arg_conv_name , arg_conv_cleanup = arg_conv_cleanup ,
@@ -288,12 +297,13 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
288297 ret_conv_name = ty_info .var_name + "_conv" , to_hu_conv = None , to_hu_conv_name = None , from_hu_conv = None )
289298 base_conv = ty_info .rust_obj + " " + ty_info .var_name + "_conv = *(" + ty_info .rust_obj + "*)(((uint64_t)" + ty_info .var_name + ") & ~1);"
290299 if ty_info .rust_obj in self .trait_structs :
291- ret_conv = (ty_info .rust_obj + "* ret = MALLOC(sizeof(" + ty_info .rust_obj + "), \" " + ty_info .rust_obj + "\" );\n *ret = " , ";" )
300+ ret_conv = (ty_info .rust_obj + "* " + ty_info . var_name + "_ret = MALLOC(sizeof(" + ty_info .rust_obj + "), \" " + ty_info .rust_obj + "\" );\n *" + ty_info . var_name + "_ret = " , ";" )
292301 if holds_ref :
293302 if (ty_info .rust_obj .replace ("LDK" , "" ) + "_clone" ) in self .clone_fns :
294303 ret_conv = (ret_conv [0 ] + ty_info .rust_obj .replace ("LDK" , "" ) + "_clone(&" , ");" )
295304 else :
296- ret_conv = (ret_conv [0 ], "; // Warning: We likely need to clone here, but no clone is available for " + ty_info .rust_obj )
305+ ret_conv = (ret_conv [0 ], ";\n // Warning: We likely need to clone here, but no clone is available, so we just do it for Java instances" )
306+ ret_conv = (ret_conv [0 ], ret_conv [1 ] + "" + self .consts .trait_struct_inc_refcnt (ty_info ).replace (ty_info .var_name + "_conv" , "(*" + ty_info .var_name + "_ret)" ))
297307 if not is_free :
298308 needs_full_clone = not is_free and (not ty_info .is_ptr and not holds_ref or ty_info .requires_clone == True ) and ty_info .requires_clone != False
299309 if needs_full_clone and (ty_info .rust_obj .replace ("LDK" , "" ) + "_clone" ) in self .clone_fns :
@@ -306,11 +316,11 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
306316 base_conv = base_conv + "\n " + "FREE((void*)" + ty_info .var_name + ");"
307317 return ConvInfo (ty_info = ty_info , arg_name = ty_info .var_name ,
308318 arg_conv = base_conv , arg_conv_name = ty_info .var_name + "_conv" , arg_conv_cleanup = None ,
309- ret_conv = ret_conv , ret_conv_name = "(uint64_t)ret " ,
319+ ret_conv = ret_conv , ret_conv_name = "(uint64_t)" + ty_info . var_name + "_ret " ,
310320 to_hu_conv = ty_info .java_hu_ty + " ret_hu_conv = new " + ty_info .java_hu_ty + "(null, " + ty_info .var_name + ");\n ret_hu_conv.ptrs_to.add(this);" ,
311321 to_hu_conv_name = "ret_hu_conv" ,
312322 from_hu_conv = (ty_info .var_name + " == null ? 0 : " + ty_info .var_name + ".ptr" , "this.ptrs_to.add(" + ty_info .var_name + ")" ))
313- needs_full_clone = not is_free and (( not ty_info .is_ptr and not holds_ref ) or ty_info .requires_clone == True ) and ty_info .requires_clone != False
323+ needs_full_clone = not is_free and (not ty_info .is_ptr or ty_info .requires_clone == True ) and ty_info .requires_clone != False
314324 if needs_full_clone :
315325 if "res" in ty_info .var_name : # XXX: This is a stupid hack
316326 needs_full_clone = False
@@ -323,6 +333,18 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
323333 # underlying unlike Vecs, and it gives Java more freedom.
324334 base_conv = base_conv + "\n FREE((void*)" + ty_info .var_name + ");"
325335 if ty_info .rust_obj in self .complex_enums :
336+ if needs_full_clone and (ty_info .rust_obj .replace ("LDK" , "" ) + "_clone" ) not in self .clone_fns :
337+ # We really need a full clone here, but for now we just implement
338+ # a manual clone explicitly for Option<Trait>s
339+ if ty_info .rust_obj .startswith ("LDKCOption" ):
340+ optional_ty = ty_info .rust_obj [11 :- 1 ]
341+ if "LDK" + optional_ty in self .trait_structs :
342+ base_conv += "\n if (" + ty_info .var_name + "_conv.tag == " + ty_info .rust_obj + "_Some) {"
343+ base_conv += "\n \t // Manually implement clone for Java trait instances"
344+ optional_ty_info = self .java_c_types ("LDK" + optional_ty + " " + ty_info .var_name , None )
345+ base_conv += self .consts .trait_struct_inc_refcnt (optional_ty_info ).\
346+ replace ("\n " , "\n \t " ).replace (ty_info .var_name + "_conv" , ty_info .var_name + "_conv.some" )
347+ base_conv += "\n }"
326348 ret_conv = ("uint64_t " + ty_info .var_name + "_ref = ((uint64_t)&" , ") | 1;" )
327349 if not holds_ref :
328350 ret_conv = (ty_info .rust_obj + " *" + ty_info .var_name + "_copy = MALLOC(sizeof(" + ty_info .rust_obj + "), \" " + ty_info .rust_obj + "\" );\n " , "" )
@@ -385,6 +407,8 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
385407 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" )))
386408 if conv_map .from_hu_conv [1 ] != "" :
387409 from_hu_conv_sfx = from_hu_conv_sfx + conv_map .from_hu_conv [1 ].replace (conv .var_name , ty_info .var_name + "." + chr (idx + ord ("a" )))
410+ if idx != len (self .tuple_types [ty_info .rust_obj ][0 ]) - 1 :
411+ from_hu_conv_sfx += "; "
388412 else :
389413 from_hu_conv = from_hu_conv + ty_info .var_name + "." + chr (idx + ord ("a" ))
390414
@@ -427,10 +451,15 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
427451 elif ty_info .is_ptr :
428452 assert (not is_free )
429453 if ty_info .rust_obj in self .complex_enums :
454+ ret_conv = ("uint64_t ret_" + ty_info .var_name + " = (uint64_t)" , " | 1; // Warning: We should clone here!" )
455+ if ty_info .rust_obj .replace ("LDK" , "" ) + "_clone" in self .clone_fns :
456+ ret_conv_pfx = ty_info .rust_obj + " *ret_" + ty_info .var_name + " = MALLOC(sizeof(" + ty_info .rust_obj + "), \" " + ty_info .rust_obj + " ret conversion\" );\n "
457+ ret_conv_pfx += "*ret_" + ty_info .var_name + " = " + ty_info .rust_obj .replace ("LDK" , "" ) + "_clone("
458+ ret_conv = (ret_conv_pfx , ");" )
430459 return ConvInfo (ty_info = ty_info , arg_name = ty_info .var_name ,
431460 arg_conv = ty_info .rust_obj + "* " + ty_info .var_name + "_conv = (" + ty_info .rust_obj + "*)" + ty_info .var_name + ";" ,
432461 arg_conv_name = ty_info .var_name + "_conv" , arg_conv_cleanup = None ,
433- ret_conv = ( "uint64_t ret_" + ty_info . var_name + " = (uint64_t)" , ";" ), ret_conv_name = "ret_" + ty_info .var_name ,
462+ ret_conv = ret_conv , ret_conv_name = "(uint64_t) ret_" + ty_info .var_name ,
434463 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 + ");" ,
435464 to_hu_conv_name = ty_info .var_name + "_hu_conv" ,
436465 from_hu_conv = (ty_info .var_name + " == null ? 0 : " + ty_info .var_name + ".ptr & ~1" , "this.ptrs_to.add(" + ty_info .var_name + ")" ))
0 commit comments