Skip to content

Commit 13cdf8b

Browse files
authored
Merge pull request #114 from TheBlueMatt/main
Change where the opaque struct is_owned bit is stored in pointers
2 parents 86706cd + 9760d53 commit 13cdf8b

File tree

564 files changed

+60124
-67287
lines changed

Some content is hidden

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

564 files changed

+60124
-67287
lines changed

gen_type_mapping.py

Lines changed: 54 additions & 61 deletions
Large diffs are not rendered by default.

genbindings.py

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ def java_c_types(fn_arg, ret_arr_len):
302302
arr_ty = "uint64_t"
303303
fn_arg = fn_arg[8:].strip()
304304
else:
305-
java_ty = consts.ptr_native_ty
306-
c_ty = consts.ptr_c_ty
305+
java_ty = consts.usize_native_ty
306+
c_ty = consts.usize_c_ty
307307
arr_ty = "uintptr_t"
308308
rust_obj = "uintptr_t"
309309
fn_arg = fn_arg[9:].strip()
@@ -434,7 +434,66 @@ def java_c_types(fn_arg, ret_arr_len):
434434

435435
# Define some manual clones...
436436
clone_fns.add("ThirtyTwoBytes_clone")
437-
write_c("static inline struct LDKThirtyTwoBytes ThirtyTwoBytes_clone(const struct LDKThirtyTwoBytes *orig) { struct LDKThirtyTwoBytes ret; memcpy(ret.data, orig->data, 32); return ret; }\n")
437+
write_c("static inline struct LDKThirtyTwoBytes ThirtyTwoBytes_clone(const struct LDKThirtyTwoBytes *orig) { struct LDKThirtyTwoBytes ret; memcpy(ret.data, orig->data, 32); return ret; }\n\n")
438+
439+
440+
write_c("static inline void* untag_ptr(uint64_t ptr) {\n")
441+
write_c("\tif (ptr < 4096) return (void*)ptr;\n")
442+
write_c("\tif (sizeof(void*) == 4) {\n")
443+
write_c("\t\t// For 32-bit systems, store pointers as 64-bit ints and use the 31st bit\n")
444+
write_c("\t\treturn (void*)(uintptr_t)ptr;\n")
445+
write_c("\t} else {\n")
446+
write_c("\t\t// For 64-bit systems, assume the top byte is used for tagging, then\n")
447+
write_c("\t\t// use bit 9 ^ bit 10.\n")
448+
write_c("\t\tuint64_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n")
449+
write_c("\t\tuintptr_t p = (ptr & ~(1ULL << 55)) | (tenth_bit << 55);\n")
450+
write_c("#ifdef LDK_DEBUG_BUILD\n")
451+
write_c("\t\t// On debug builds we also use the 11th bit as a debug flag\n")
452+
write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n")
453+
write_c("\t\tCHECK(tenth_bit != eleventh_bit);\n")
454+
write_c("\t\tp ^= 1ULL << 53;\n")
455+
write_c("#endif\n")
456+
write_c("\t\treturn (void*)p;\n")
457+
write_c("\t}\n")
458+
write_c("}\n")
459+
460+
write_c("static inline bool ptr_is_owned(uint64_t ptr) {\n")
461+
write_c("\tif(ptr < 4096) return true;\n")
462+
write_c("\tif (sizeof(void*) == 4) {\n")
463+
write_c("\t\treturn ptr & (1ULL << 32);\n")
464+
write_c("\t} else {\n")
465+
write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n")
466+
write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n")
467+
write_c("#ifdef LDK_DEBUG_BUILD\n")
468+
write_c("\t\t// On debug builds we also use the 11th bit as a debug flag\n")
469+
write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n")
470+
write_c("\t\tCHECK(tenth_bit != eleventh_bit);\n")
471+
write_c("#endif\n")
472+
write_c("\t\treturn (ninth_bit ^ tenth_bit) ? true : false;\n")
473+
write_c("\t}\n")
474+
write_c("}\n")
475+
476+
write_c("static inline uint64_t tag_ptr(const void* ptr, bool is_owned) {\n")
477+
write_c("\tif ((uintptr_t)ptr < 4096) return (uint64_t)ptr;\n")
478+
write_c("\tif (sizeof(void*) == 4) {\n")
479+
write_c("\t\treturn (((uint64_t)ptr) | ((is_owned ? 1ULL : 0) << 32));\n")
480+
write_c("\t} else {\n")
481+
write_c("\t\tCHECK(sizeof(uintptr_t) == 8);\n")
482+
write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n")
483+
write_c("\t\tuintptr_t t = (((uintptr_t)ptr) | (((is_owned ? 1ULL : 0ULL) ^ tenth_bit) << 55));\n")
484+
write_c("#ifdef LDK_DEBUG_BUILD\n")
485+
write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n")
486+
write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n")
487+
write_c("\t\tCHECK(ninth_bit == tenth_bit);\n")
488+
write_c("\t\tCHECK(ninth_bit == eleventh_bit);\n")
489+
write_c("\t\tt ^= 1ULL << 53;\n")
490+
write_c("#endif\n")
491+
write_c("\t\tCHECK(ptr_is_owned(t) == is_owned);\n")
492+
write_c("\t\tCHECK(untag_ptr(t) == ptr);\n")
493+
#write_c("\t\tCHECK(untag_ptr((uintptr_t)untag_ptr(t)) == ptr);\n")
494+
write_c("\t\treturn t;\n")
495+
write_c("\t}\n")
496+
write_c("}\n\n")
438497

439498
java_c_types_none_allowed = False # C structs created by cbindgen are declared in dependency order
440499

@@ -480,13 +539,13 @@ def map_fn_with_ref_option(line, re_match, ret_arr_len, c_call_string, doc_comme
480539
return_type_info = type_mapping_generator.map_type(method_return_type.strip() + " ret", True, ret_arr_len, False, force_holds_ref)
481540

482541
if method_name.endswith("_clone") and expected_struct not in unitary_enums:
483-
meth_line = "uintptr_t " + expected_struct.replace("LDK", "") + "_clone_ptr(" + expected_struct + " *NONNULL_PTR arg)"
542+
meth_line = "uint64_t " + expected_struct.replace("LDK", "") + "_clone_ptr(" + expected_struct + " *NONNULL_PTR arg)"
484543
write_c("static inline " + meth_line + " {\n")
485544
write_c("\t" + return_type_info.ret_conv[0].replace("\n", "\n\t"))
486545
write_c(method_name + "(arg)")
487-
write_c(return_type_info.ret_conv[1])
546+
write_c(return_type_info.ret_conv[1].replace("\n", "\n\t"))
488547
write_c("\n\treturn " + return_type_info.ret_conv_name + ";\n}\n")
489-
map_fn(meth_line + ";\n", re.compile("(uintptr_t) ([A-Za-z_0-9]*)\((.*)\)").match(meth_line), None, None, None)
548+
map_fn(meth_line + ";\n", re.compile("(uint64_t) ([A-Za-z_0-9]*)\((.*)\)").match(meth_line), None, None, None)
490549

491550
argument_types = []
492551
default_constructor_args = {}
@@ -575,7 +634,7 @@ def map_fn_with_ref_option(line, re_match, ret_arr_len, c_call_string, doc_comme
575634
assert return_type_info.c_ty == "void"
576635
write_c(consts.c_fn_ty_pfx + "void " + consts.c_fn_name_define_pfx(method_name, True) + argument_types[0].c_ty + " " + argument_types[0].ty_info.var_name + ") {\n")
577636
if argument_types[0].ty_info.passed_as_ptr and not argument_types[0].ty_info.rust_obj in opaque_structs:
578-
write_c("\tif ((" + argument_types[0].ty_info.var_name + " & 1) != 0) return;\n")
637+
write_c("\tif (!ptr_is_owned(" + argument_types[0].ty_info.var_name + ")) return;\n")
579638

580639
for info in argument_types:
581640
if info.arg_conv is not None:

java_strings.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,9 @@ class CommonBase {
555555
self.file_ext = ".java"
556556
self.ptr_c_ty = "int64_t"
557557
self.ptr_native_ty = "long"
558+
self.usize_c_ty = "int64_t"
559+
self.usize_native_ty = "long"
560+
self.native_zero_ptr = "0"
558561
self.result_c_ty = "jclass"
559562
self.ptr_arr = "jobjectArray"
560563
self.is_arr_some_check = ("", " != NULL")
@@ -1105,7 +1108,7 @@ def native_c_map_trait(self, struct_name, field_vars, flattened_field_vars, fiel
11051108
else:
11061109
out_c = out_c + ", " + var[1]
11071110
out_c = out_c + ");\n"
1108-
out_c = out_c + "\treturn (uint64_t)res_ptr;\n"
1111+
out_c = out_c + "\treturn tag_ptr(res_ptr, true);\n"
11091112
out_c = out_c + "}\n"
11101113

11111114
for var in flattened_field_vars:
@@ -1124,10 +1127,8 @@ def native_c_map_trait(self, struct_name, field_vars, flattened_field_vars, fiel
11241127
out_java += "\tpublic static native long " + struct_name + "_get_" + var[1] + "(long arg);\n"
11251128

11261129
out_c += "JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_" + struct_name + "_1get_1" + var[1] + "(JNIEnv *env, jclass clz, int64_t arg) {\n"
1127-
out_c += "\t" + struct_name + " *inp = (" + struct_name + " *)(arg & ~1);\n"
1128-
out_c += "\tuint64_t res_ptr = (uint64_t)&inp->" + var[1] + ";\n"
1129-
out_c += "\tDO_ASSERT((res_ptr & 1) == 0);\n"
1130-
out_c += "\treturn (int64_t)(res_ptr | 1);\n"
1130+
out_c += "\t" + struct_name + " *inp = (" + struct_name + " *)untag_ptr(arg);\n"
1131+
out_c += "\treturn tag_ptr(&inp->" + var[1] + ", false);\n"
11311132
out_c += "}\n"
11321133

11331134
return (out_java, out_java_trait, out_c)
@@ -1217,7 +1218,7 @@ def map_complex_enum(self, struct_name, variant_list, camel_to_snake, enum_doc_c
12171218
out_c += (self.c_complex_enum_pfx(struct_name, [x.var_name for x in variant_list], init_meth_jty_strs))
12181219

12191220
out_c += (self.c_fn_ty_pfx + self.c_complex_enum_pass_ty(struct_name) + " " + self.c_fn_name_define_pfx(struct_name + "_ref_from_ptr", True) + self.ptr_c_ty + " ptr) {\n")
1220-
out_c += ("\t" + struct_name + " *obj = (" + struct_name + "*)(ptr & ~1);\n")
1221+
out_c += ("\t" + struct_name + " *obj = (" + struct_name + "*)untag_ptr(ptr);\n")
12211222
out_c += ("\tswitch(obj->tag) {\n")
12221223
for var in variant_list:
12231224
out_c += ("\t\tcase " + struct_name + "_" + var.var_name + ": {\n")

0 commit comments

Comments
 (0)