X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=genbindings.py;h=a7c0a20f67fe918b44b1ec9aa9901bbfc0d68e65;hb=1f8ac33c53ba371193ed1e543038b83c2f52da8e;hp=2d69168ef89fef95411b4a608a9120c7e2cb323e;hpb=9aa1eebc40df06586c7ab12f7c8eb22ebcb8b365;p=ldk-java diff --git a/genbindings.py b/genbindings.py index 2d69168e..a7c0a20f 100755 --- a/genbindings.py +++ b/genbindings.py @@ -263,14 +263,19 @@ def java_c_types(fn_arg, ret_arr_len): arr_ty = "uint8_t" fn_arg = fn_arg[7:].strip() is_primitive = True - elif fn_arg.startswith("LDKu5"): + elif fn_arg.startswith("LDKu5") or fn_arg.startswith("LDKWitnessVersion"): java_ty = consts.c_type_map['uint8_t'][0] - java_hu_ty = "UInt5" - rust_obj = "LDKu5" + if fn_arg.startswith("LDKu5"): + java_hu_ty = "UInt5" + rust_obj = "LDKu5" + fn_arg = fn_arg[6:].strip() + else: + java_hu_ty = "WitnessVersion" + rust_obj = "LDKWitnessVersion" + fn_arg = fn_arg[18:].strip() c_ty = "int8_t" arr_ty = "uint8_t" fn_ty_arg = "B" - fn_arg = fn_arg[6:].strip() elif fn_arg.startswith("uint16_t"): mapped_type = consts.c_type_map['uint16_t'] java_ty = mapped_type[0] @@ -429,7 +434,65 @@ with open(sys.argv[1]) as in_h: # Define some manual clones... clone_fns.add("ThirtyTwoBytes_clone") -write_c("static inline struct LDKThirtyTwoBytes ThirtyTwoBytes_clone(const struct LDKThirtyTwoBytes *orig) { struct LDKThirtyTwoBytes ret; memcpy(ret.data, orig->data, 32); return ret; }\n") +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") + + +write_c("static inline void* untag_ptr(uintptr_t ptr) {\n") +write_c("\tif (ptr < 4096) return (void*)ptr;\n") +write_c("\tif (sizeof(void*) == 4) {\n") +write_c("\t\treturn (void*)(ptr & ~1);\n") +write_c("\t} else {\n") +write_c("\t\t// For 64-bit systems, assume the top byte is used for tagging, then\n") +write_c("\t\t// use bit 9 ^ bit 10.\n") +write_c("\t\tuint64_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n") +write_c("\t\tuintptr_t p = (ptr & ~(1ULL << 55)) | (tenth_bit << 55);\n") +write_c("#ifdef LDK_DEBUG_BUILD\n") +write_c("\t\t// On debug builds we also use the 11th bit as a debug flag\n") +write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n") +write_c("\t\tCHECK(tenth_bit != eleventh_bit);\n") +write_c("\t\tp ^= 1ULL << 53;\n") +write_c("#endif\n") +write_c("\t\treturn (void*)p;\n") +write_c("\t}\n") +write_c("}\n") + +write_c("static inline bool ptr_is_owned(uintptr_t ptr) {\n") +write_c("\tif(ptr < 4096) return true;\n") +write_c("\tif (sizeof(void*) == 4) {\n") +write_c("\t\treturn (ptr & 1) ? true : false;\n") +write_c("\t} else {\n") +write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n") +write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n") +write_c("#ifdef LDK_DEBUG_BUILD\n") +write_c("\t\t// On debug builds we also use the 11th bit as a debug flag\n") +write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n") +write_c("\t\tCHECK(tenth_bit != eleventh_bit);\n") +write_c("#endif\n") +write_c("\t\treturn (ninth_bit ^ tenth_bit) ? true : false;\n") +write_c("\t}\n") +write_c("}\n") + +write_c("static inline uintptr_t tag_ptr(const void* ptr, bool is_owned) {\n") +write_c("\tif ((uintptr_t)ptr < 4096) return (uint64_t)ptr;\n") +write_c("\tif (sizeof(void*) == 4) {\n") +write_c("\t\treturn ((uintptr_t)ptr) | (is_owned ? 1 : 0);\n") +write_c("\t} else {\n") +write_c("\t\tCHECK(sizeof(uintptr_t) == 8);\n") +write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n") +write_c("\t\tuintptr_t t = (((uintptr_t)ptr) | (((is_owned ? 1ULL : 0ULL) ^ tenth_bit) << 55));\n") +write_c("#ifdef LDK_DEBUG_BUILD\n") +write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n") +write_c("\t\tuintptr_t eleventh_bit = (((uintptr_t)ptr) & (1ULL << 53)) >> 53;\n") +write_c("\t\tCHECK(ninth_bit == tenth_bit);\n") +write_c("\t\tCHECK(ninth_bit == eleventh_bit);\n") +write_c("\t\tt ^= 1ULL << 53;\n") +write_c("#endif\n") +write_c("\t\tCHECK(ptr_is_owned(t) == is_owned);\n") +write_c("\t\tCHECK(untag_ptr(t) == ptr);\n") +#write_c("\t\tCHECK(untag_ptr((uintptr_t)untag_ptr(t)) == ptr);\n") +write_c("\t\treturn t;\n") +write_c("\t}\n") +write_c("}\n\n") java_c_types_none_allowed = False # C structs created by cbindgen are declared in dependency order @@ -479,7 +542,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", write_c("static inline " + meth_line + " {\n") write_c("\t" + return_type_info.ret_conv[0].replace("\n", "\n\t")) write_c(method_name + "(arg)") - write_c(return_type_info.ret_conv[1]) + write_c(return_type_info.ret_conv[1].replace("\n", "\n\t")) write_c("\n\treturn " + return_type_info.ret_conv_name + ";\n}\n") map_fn(meth_line + ";\n", re.compile("(uintptr_t) ([A-Za-z_0-9]*)\((.*)\)").match(meth_line), None, None, None) @@ -570,7 +633,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", assert return_type_info.c_ty == "void" 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") if argument_types[0].ty_info.passed_as_ptr and not argument_types[0].ty_info.rust_obj in opaque_structs: - write_c("\tif ((" + argument_types[0].ty_info.var_name + " & 1) != 0) return;\n") + write_c("\tif (!ptr_is_owned(" + argument_types[0].ty_info.var_name + ")) return;\n") for info in argument_types: if info.arg_conv is not None: @@ -648,7 +711,13 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", elif camel_to_snake(variant_name) in inline_enum_variants: # TODO: If we ever have a rust enum Variant(Option) we need to pipe # docs through to there, and then potentially mark the field nullable. - mapped = type_mapping_generator.map_type(inline_enum_variants[camel_to_snake(variant_name)] + " " + camel_to_snake(variant_name), False, None, False, True) + (variant_info, variant_field_docs) = inline_enum_variants[camel_to_snake(variant_name)] + variant_ty_text = variant_info + " " + camel_to_snake(variant_name) + variant_ty_info = type_mapping_generator.java_c_types(variant_ty_text, None) + if variant_field_docs is not None and doc_to_field_nullable(variant_field_docs): + mapped = type_mapping_generator.map_type_with_info(variant_ty_info, False, None, False, True, True) + else: + mapped = type_mapping_generator.map_type_with_info(variant_ty_info, False, None, False, True, False) contains_trait |= mapped.ty_info.contains_trait fields.append((mapped, None)) enum_variants.append(ComplexEnumVariantInfo(variant_name, variant_docs, fields, True)) @@ -939,7 +1008,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", elif struct_name in union_enum_items: tuple_variants = {} elem_items = -1 - for line, _ in field_lines: + for line, field_block_comment in field_lines: if line == " struct {": elem_items = 0 elif line == " };": @@ -952,7 +1021,7 @@ with open(sys.argv[1]) as in_h, open(f"{sys.argv[2]}/bindings{consts.file_ext}", line = line[5:] split = line.split(" ") assert len(split) == 2 - tuple_variants[split[1].strip(";")] = split[0] + tuple_variants[split[1].strip(";")] = (split[0], field_block_comment) elem_items += 1 if elem_items > 1: # We don't currently support tuple variant with more than one element