From: Matt Corallo Date: Mon, 1 Feb 2021 00:36:46 +0000 (-0500) Subject: Wipe Java objects when we move them into rust (only for features) X-Git-Tag: v0.0.1~15 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=01fa6524ef026ef4fe971cf625f687ddf03543d2;p=ldk-java Wipe Java objects when we move them into rust (only for features) --- diff --git a/gen_type_mapping.py b/gen_type_mapping.py index aebd7d01..1a7befb6 100644 --- a/gen_type_mapping.py +++ b/gen_type_mapping.py @@ -206,6 +206,7 @@ class TypeMappingGenerator: ty_info.var_name = "ret" if ty_info.rust_obj in self.opaque_structs: + from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".ptr & ~1", "this.ptrs_to.add(" + ty_info.var_name + ")") 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 ty_info.is_ptr and holds_ref: @@ -217,7 +218,16 @@ class TypeMappingGenerator: # 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 + "\n" + ty_info.var_name + "_conv = " + ty_info.rust_obj.replace("LDK", "") + "_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 no clone is available for " + ty_info.rust_obj + opaque_arg_conv = opaque_arg_conv + "\n// Warning: we need a move here but no clone is available for " + ty_info.rust_obj + # TODO: Once we support features cloning (which just isn't in C yet), we can make this a compile error instead! + from_hu_conv = (from_hu_conv[0], from_hu_conv[1] + ";\n" + + "// Due to rust's strict-ownership memory model, in some cases we need to \"move\"\n" + + "// an object to pass exclusive ownership to the function being called.\n" + + "// In most cases, we avoid this being visible in GC'd languages by cloning the object\n" + + "// at the FFI layer, creating a new object which Rust can claim ownership of\n" + + "// However, in some cases (eg here), there is no way to clone an object, and thus\n" + + "// we actually have to pass full ownership to Rust.\n" + + "// Thus, after this call, " + ty_info.var_name + " is reset to null and is now a dummy object.\n" + ty_info.var_name + ".ptr = 0") opaque_ret_conv_suf = ";\n" if not holds_ref and ty_info.is_ptr and (ty_info.rust_obj.replace("LDK", "") + "_clone") in self.clone_fns: # is_ptr, not holds_ref implies passing a pointed-to value to java, which needs copied @@ -242,7 +252,7 @@ class TypeMappingGenerator: ret_conv_name = ty_info.var_name + "_ref", to_hu_conv = self.consts.to_hu_conv_templates['ptr'].replace('{human_type}', ty_info.java_hu_ty).replace('{var_name}', 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 + ")")) + from_hu_conv = from_hu_conv) else: 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, @@ -250,7 +260,7 @@ class TypeMappingGenerator: ret_conv_name = ty_info.var_name + "_ref", to_hu_conv = self.consts.to_hu_conv_templates['default'].replace('{human_type}', ty_info.java_hu_ty).replace('{var_name}', 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 + ")")) + from_hu_conv = from_hu_conv) if not ty_info.is_ptr: if ty_info.rust_obj in self.unitary_enums: diff --git a/java_strings.py b/java_strings.py index fc1e4099..bc3c73cf 100644 --- a/java_strings.py +++ b/java_strings.py @@ -61,7 +61,7 @@ public class UtilMethods { self.common_base = """package org.ldk.structs; import java.util.LinkedList; class CommonBase { - final long ptr; + long ptr; LinkedList ptrs_to = new LinkedList(); protected CommonBase(long ptr) { this.ptr = ptr; } public long _test_only_get_ptr() { return this.ptr; }