Skip to content

Commit 7d6be8a

Browse files
authored
Merge pull request #45 from TheBlueMatt/main
Various fixes + cut 0.0.101
2 parents bfce5a7 + a7653cf commit 7d6be8a

File tree

167 files changed

+18256
-5105
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+18256
-5105
lines changed

.github/workflows/build.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
cd ..
3636
git clone https://github.com/lightningdevkit/ldk-c-bindings
3737
cd ldk-c-bindings
38-
git checkout 0.0.100
38+
git checkout 0.0.101
3939
- name: Rebuild C bindings without STD for WASM
4040
run: |
4141
cd ldk-c-bindings
@@ -98,14 +98,16 @@ jobs:
9898
cp ldk-java-classes.jar "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
9999
cp ldk-java-javadoc.jar "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
100100
cd ldk-java-bins
101+
# ldk-java-leaktracking is only for debug purposes and we don't bother with determinism
102+
git checkout "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-leaktracking.jar"
101103
if ! git diff --exit-code; then
102104
mv "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"* ./
103105
git checkout "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
104106
apt-get -y install diffoscope
105-
diffoscope ldk-java-sources.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-sources.jar"
106-
diffoscope ldk-java-javadoc.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-javadoc.jar"
107-
diffoscope ldk-java-classes.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-classes.jar"
108-
diffoscope ldk-java.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java.jar"
107+
diffoscope ldk-java-sources.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-sources.jar" || echo
108+
diffoscope ldk-java-javadoc.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-javadoc.jar" || echo
109+
diffoscope ldk-java-classes.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-classes.jar" || echo
110+
diffoscope ldk-java.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java.jar" || echo
109111
exit 1
110112
fi
111113
- name: Run Java Tests against built release jar
@@ -165,7 +167,7 @@ jobs:
165167
cd ..
166168
git clone https://github.com/lightningdevkit/ldk-c-bindings
167169
cd ldk-c-bindings
168-
git checkout 0.0.100
170+
git checkout 0.0.101
169171
- name: Detect current git version
170172
run: |
171173
# We assume the top commit is just a bindings update commit, so we
@@ -245,7 +247,7 @@ jobs:
245247
cd ..
246248
git clone https://github.com/lightningdevkit/ldk-c-bindings
247249
cd ldk-c-bindings
248-
git checkout 0.0.100
250+
git checkout 0.0.101
249251
- name: Rebuild C bindings with upstream clang, and check the sample app builds + links
250252
run: |
251253
cd ldk-c-bindings

build-release-jar.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ ls src/main/resources/liblightningjni_MacOSX-aarch64.nativelib
1111

1212
export LANG=C
1313

14+
# We need to fetch dependencies first as faketime will break PKI cert checks!
15+
mvn -DskipTests=true -Dorg.lightningdevkit.skipdocs=false package
1416
mvn clean
1517
faketime 2021-01-01 mvn -DskipTests=true -Dorg.lightningdevkit.skipdocs=false package
1618

gen_type_mapping.py

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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 += ";\nfor (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 + ");\nret_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 + "\nFREE((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 += "\nif (" + 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 + ")"))

genbindings.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,23 @@ def map_fn(line, re_match, ret_arr_len, c_call_string, doc_comment):
459459
takes_self_ptr = True
460460
elif argument_conversion_info.arg_name in params_nullable:
461461
argument_conversion_info.nullable = True
462+
if argument_conversion_info.arg_conv is not None and "Warning" in argument_conversion_info.arg_conv:
463+
arg_ty_info = java_c_types(argument, None)
464+
print("WARNING: Remapping argument " + arg_ty_info.var_name + " of function " + method_name + " to a reference")
465+
print(" The argument appears to require a move, or not clonable, and is nullable.")
466+
print(" Normally for arguments that require a move and are not clonable, we split")
467+
print(" the argument into the type's constructor's arguments and just use those to")
468+
print(" construct a new object on the fly.")
469+
print(" However, because the object is nullable, doing so would mean we can no")
470+
print(" longer allow the user to pass null, as we now have an argument list instead.")
471+
print(" Thus, we blindly assume its really an Option<&Type> instead of an Option<Type>.")
472+
print(" It may or may not actually be a reference, but its the simplest mapping option")
473+
print(" and also the only use of this code today.")
474+
arg_ty_info.requires_clone = False
475+
argument_conversion_info = type_mapping_generator.map_type_with_info(arg_ty_info, False, None, is_free, True)
476+
assert argument_conversion_info.arg_conv is not None and "Warning" not in argument_conversion_info.arg_conv
477+
462478
if argument_conversion_info.arg_conv is not None and "Warning" in argument_conversion_info.arg_conv:
463-
assert not argument_conversion_info.arg_name in params_nullable
464479
if argument_conversion_info.rust_obj in constructor_fns:
465480
assert not is_free
466481
for explode_arg in constructor_fns[argument_conversion_info.rust_obj].split(','):

0 commit comments

Comments
 (0)