Skip to content

Commit 7cbcc5e

Browse files
committed
Switch 32-bit platforms to using 64-bit "pointers"
This much more cleanly fixes the issue described in the previous commit by simply using 64-bit integers to represent pointers on 32-bit platforms, letting us store the required flag bit in the top 32-bits that are always free. It does, however, imply changing the entire call semantics for TypeScript to use BigInts for pointers, rather than numbers.
1 parent 1f8ac33 commit 7cbcc5e

File tree

5 files changed

+74
-47
lines changed

5 files changed

+74
-47
lines changed

gen_type_mapping.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
282282
ty_info.var_name = "ret"
283283

284284
if ty_info.rust_obj in self.opaque_structs:
285-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + self.consts.get_ptr(ty_info.var_name), self.consts.add_ref("this", ty_info.var_name))
285+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + self.consts.get_ptr(ty_info.var_name), self.consts.add_ref("this", ty_info.var_name))
286286
opaque_arg_conv = ty_info.rust_obj + " " + ty_info.var_name + "_conv;\n"
287287
opaque_arg_conv = opaque_arg_conv + ty_info.var_name + "_conv.inner = untag_ptr(" + ty_info.var_name + ");\n"
288288
opaque_arg_conv += ty_info.var_name + "_conv.is_owned = ptr_is_owned(" + ty_info.var_name + ");\n"
@@ -298,7 +298,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
298298
if holds_ref:
299299
opaque_arg_conv += "\n" + ty_info.var_name + "_conv = " + ty_info.rust_obj.replace("LDK", "") + "_clone(&" + ty_info.var_name + "_conv);"
300300
else:
301-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".clone_ptr()", "")
301+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + ty_info.var_name + ".clone_ptr()", "")
302302
elif ty_info.passed_as_ptr:
303303
opaque_arg_conv += "\n// WARNING: we need a move here but no clone is available for " + ty_info.rust_obj + "\n"
304304
# TODO: Once we support features cloning (which just isn't in C yet), we can make this a compile error instead!
@@ -380,7 +380,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
380380
if holds_ref:
381381
base_conv += "\n" + ty_info.var_name + "_conv = " + ty_info.rust_obj.replace("LDK", "") + "_clone(&" + ty_info.var_name + "_conv);"
382382
else:
383-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".clone_ptr()", "")
383+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + ty_info.var_name + ".clone_ptr()", "")
384384
base_conv += "\n" + "FREE(untag_ptr(" + ty_info.var_name + "));"
385385
else:
386386
base_conv = base_conv + self.consts.trait_struct_inc_refcnt(ty_info)
@@ -389,7 +389,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
389389
else:
390390
base_conv = base_conv + "\n" + "FREE(untag_ptr(" + ty_info.var_name + "));"
391391
if from_hu_conv is None:
392-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + self.consts.get_ptr(ty_info.var_name), "")
392+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + self.consts.get_ptr(ty_info.var_name), "")
393393
from_hu_conv = (from_hu_conv[0], self.consts.add_ref("this", ty_info.var_name))
394394
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
395395
arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
@@ -408,7 +408,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
408408
if holds_ref:
409409
base_conv += "\n" + ty_info.var_name + "_conv = " + ty_info.rust_obj.replace("LDK", "") + "_clone((" + ty_info.rust_obj + "*)untag_ptr(" + ty_info.var_name + "));"
410410
else:
411-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + ty_info.var_name + ".clone_ptr()", "")
411+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + ty_info.var_name + ".clone_ptr()", "")
412412
base_conv += "\n" + "FREE(untag_ptr(" + ty_info.var_name + "));"
413413
elif needs_full_clone:
414414
base_conv = base_conv + "\n// WARNING: we may need a move here but no clone is available for " + ty_info.rust_obj
@@ -456,7 +456,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
456456
else:
457457
ret_conv = (ty_info.rust_obj + "* " + ty_info.var_name + "_conv = MALLOC(sizeof(" + ty_info.rust_obj + "), \"" + ty_info.rust_obj + "\");\n*" + ty_info.var_name + "_conv = ", ";")
458458
if from_hu_conv is None:
459-
from_hu_conv = (ty_info.var_name + " != null ? " + self.consts.get_ptr(ty_info.var_name) + " : 0", "")
459+
from_hu_conv = (ty_info.var_name + " != null ? " + self.consts.get_ptr(ty_info.var_name) + " : " + self.consts.native_zero_ptr, "")
460460
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
461461
arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
462462
ret_conv = ret_conv, ret_conv_name = "tag_ptr(" + ty_info.var_name + "_conv, true)",
@@ -482,7 +482,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
482482
else:
483483
to_hu_conv_sfx = ""
484484
if from_hu_conv is None:
485-
from_hu_conv = (ty_info.var_name + " != null ? " + self.consts.get_ptr(ty_info.var_name) + " : 0", "")
485+
from_hu_conv = (ty_info.var_name + " != null ? " + self.consts.get_ptr(ty_info.var_name) + " : " + self.consts.native_zero_ptr, "")
486486
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
487487
arg_conv = base_conv, arg_conv_name = ty_info.var_name + "_conv", arg_conv_cleanup = None,
488488
ret_conv = ret_conv, ret_conv_name = ret_conv_name,
@@ -535,7 +535,7 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
535535
ret_conv = ret_conv, ret_conv_name = "ref_" + ty_info.var_name,
536536
to_hu_conv = self.consts.var_decl_statement(ty_info.java_hu_ty, ty_info.var_name + "_hu_conv", ty_info.java_hu_ty + ".constr_from_ptr(" + ty_info.var_name + ")") + ";",
537537
to_hu_conv_name = ty_info.var_name + "_hu_conv",
538-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + self.consts.get_ptr(ty_info.var_name), from_hu_sfx))
538+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + self.consts.get_ptr(ty_info.var_name), from_hu_sfx))
539539
elif ty_info.rust_obj in self.trait_structs:
540540
if ty_info.nonnull_ptr:
541541
arg_conv = "void* " + ty_info.var_name + "_ptr = untag_ptr(" + ty_info.var_name + ");\n"
@@ -564,15 +564,15 @@ def _do_map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, hold
564564
ret_conv_name = "tag_ptr(" + ty_info.var_name + "_clone, true)",
565565
to_hu_conv = self.consts.var_decl_statement(ty_info.java_hu_ty, "ret_hu_conv", "new " + ty_info.java_hu_ty + "(null, " + ty_info.var_name + ")") + ";\n" + self.consts.add_ref("ret_hu_conv", "this") + ";",
566566
to_hu_conv_name = "ret_hu_conv",
567-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + self.consts.get_ptr(ty_info.var_name), ""))
567+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + self.consts.get_ptr(ty_info.var_name), ""))
568568
else:
569569
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
570570
arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = None,
571571
ret_conv = ("// WARNING: This object doesn't live past this scope, needs clone!\n" + self.consts.ptr_c_ty + " ret_" + ty_info.var_name + " = tag_ptr(", ", false);"),
572572
ret_conv_name = "ret_" + ty_info.var_name,
573573
to_hu_conv = self.consts.var_decl_statement(ty_info.java_hu_ty, "ret_hu_conv", "new " + ty_info.java_hu_ty + "(null, " + ty_info.var_name + ")") + ";\n" + self.consts.add_ref("ret_hu_conv", "this") + ";",
574574
to_hu_conv_name = "ret_hu_conv",
575-
from_hu_conv = (ty_info.var_name + " == null ? 0 : " + self.consts.get_ptr(ty_info.var_name), self.consts.add_ref("this", ty_info.var_name)))
575+
from_hu_conv = (ty_info.var_name + " == null ? " + self.consts.native_zero_ptr + " : " + self.consts.get_ptr(ty_info.var_name), self.consts.add_ref("this", ty_info.var_name)))
576576
ret_conv = (self.consts.ptr_c_ty + " ret_" + ty_info.var_name + " = tag_ptr(", ", true);")
577577
if holds_ref:
578578
ret_conv = (ret_conv[0], ", false);")

genbindings.py

Lines changed: 11 additions & 10 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()
@@ -437,10 +437,11 @@ def java_c_types(fn_arg, ret_arr_len):
437437
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")
438438

439439

440-
write_c("static inline void* untag_ptr(uintptr_t ptr) {\n")
440+
write_c("static inline void* untag_ptr(uint64_t ptr) {\n")
441441
write_c("\tif (ptr < 4096) return (void*)ptr;\n")
442442
write_c("\tif (sizeof(void*) == 4) {\n")
443-
write_c("\t\treturn (void*)(ptr & ~1);\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")
444445
write_c("\t} else {\n")
445446
write_c("\t\t// For 64-bit systems, assume the top byte is used for tagging, then\n")
446447
write_c("\t\t// use bit 9 ^ bit 10.\n")
@@ -456,10 +457,10 @@ def java_c_types(fn_arg, ret_arr_len):
456457
write_c("\t}\n")
457458
write_c("}\n")
458459

459-
write_c("static inline bool ptr_is_owned(uintptr_t ptr) {\n")
460+
write_c("static inline bool ptr_is_owned(uint64_t ptr) {\n")
460461
write_c("\tif(ptr < 4096) return true;\n")
461462
write_c("\tif (sizeof(void*) == 4) {\n")
462-
write_c("\t\treturn (ptr & 1) ? true : false;\n")
463+
write_c("\t\treturn ptr & (1ULL << 32);\n")
463464
write_c("\t} else {\n")
464465
write_c("\t\tuintptr_t ninth_bit = (((uintptr_t)ptr) & (1ULL << 55)) >> 55;\n")
465466
write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n")
@@ -472,10 +473,10 @@ def java_c_types(fn_arg, ret_arr_len):
472473
write_c("\t}\n")
473474
write_c("}\n")
474475

475-
write_c("static inline uintptr_t tag_ptr(const void* ptr, bool is_owned) {\n")
476+
write_c("static inline uint64_t tag_ptr(const void* ptr, bool is_owned) {\n")
476477
write_c("\tif ((uintptr_t)ptr < 4096) return (uint64_t)ptr;\n")
477478
write_c("\tif (sizeof(void*) == 4) {\n")
478-
write_c("\t\treturn ((uintptr_t)ptr) | (is_owned ? 1 : 0);\n")
479+
write_c("\t\treturn (((uint64_t)ptr) | ((is_owned ? 1ULL : 0) << 32));\n")
479480
write_c("\t} else {\n")
480481
write_c("\t\tCHECK(sizeof(uintptr_t) == 8);\n")
481482
write_c("\t\tuintptr_t tenth_bit = (((uintptr_t)ptr) & (1ULL << 54)) >> 54;\n")
@@ -538,13 +539,13 @@ def map_fn_with_ref_option(line, re_match, ret_arr_len, c_call_string, doc_comme
538539
return_type_info = type_mapping_generator.map_type(method_return_type.strip() + " ret", True, ret_arr_len, False, force_holds_ref)
539540

540541
if method_name.endswith("_clone") and expected_struct not in unitary_enums:
541-
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)"
542543
write_c("static inline " + meth_line + " {\n")
543544
write_c("\t" + return_type_info.ret_conv[0].replace("\n", "\n\t"))
544545
write_c(method_name + "(arg)")
545546
write_c(return_type_info.ret_conv[1].replace("\n", "\n\t"))
546547
write_c("\n\treturn " + return_type_info.ret_conv_name + ";\n}\n")
547-
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)
548549

549550
argument_types = []
550551
default_constructor_args = {}

java_strings.py

Lines changed: 3 additions & 0 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")

ts/js-wasm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ typedef uint32_t JSValue;
3939

4040
DECL_IMPORT(u, u, u, u, u, u)
4141
DECL_IMPORT(b, u, u, u, u, u)
42+
DECL_IMPORT(b, b, u, u, u, u)
43+
DECL_IMPORT(b, b, b, u, u, u)
44+
DECL_IMPORT(b, b, b, b, u, u)
4245
DECL_IMPORT(b, b, b, b, b, b)
46+
DECL_IMPORT(u, b, u, u, b, u)
4347
DECL_IMPORT(u, b, u, u, u, u)
48+
DECL_IMPORT(u, b, b, u, u, u)
4449
DECL_IMPORT(u, u, b, u, u, u)
50+
DECL_IMPORT(u, u, b, u, b, u)
4551

4652
#endif

0 commit comments

Comments
 (0)