Change where the opaque struct is_owned bit is stored in pointers
authorMatt Corallo <git@bluematt.me>
Thu, 11 Aug 2022 21:38:05 +0000 (21:38 +0000)
committerMatt Corallo <git@bluematt.me>
Sat, 13 Aug 2022 00:39:56 +0000 (00:39 +0000)
commit1f8ac33c53ba371193ed1e543038b83c2f52da8e
treea9217dca0b5c1e612e1f50b884937c7ac4709263
parent86706cda41dcc0d47b317b1f90a9757e44915657
Change where the opaque struct is_owned bit is stored in pointers

When we're returning a reference to an opaque struct, we previously
used the LSB to track the is_owned bit. This works for
heap-allocated structs just fine as `malloc` guarantees maximal
(usually 8-byte) alignment for all returned pointers. However, for
opaque structs which are actually a reference to a field in a
larger native Rust struct (eg `NodeId` in
`ChannelDetails_get_node_one`), this may not be the case. This
caused reading off-by-one `NodeId`s.

We fix this by adding a new set of utilities which handle tagging
and un-tagging pointers which are a bit more complicated. One
32-bit platforms, we simply use the low bit but will change that
in the next commit. However, on 64-bit platforms we have to be a
bit more careful. Modern 64-bit platforms, including Android, use
the top bits (8 bits in the case of android) for pointer
authentication. x86_64 sets the top 16 bits to the same value, but
they may be 1s or 0s. Thus, we use (9th bit) ^ (10th bit) as our
tag, assuming that they are always equal.

This isn't the most robust solution, but until there's time to
rewrite all the opaque object handling to fetch java fields from C
this is likely the best we're going to be able to do.
gen_type_mapping.py
genbindings.py
java_strings.py
typescript_strings.py