Matt Corallo [Mon, 3 Oct 2022 20:07:28 +0000 (20:07 +0000)]
[TS] Fix generation for traits that have supertraits
When we have a trait with a supertrait, we have to pass both the
main- and super-trait instance indxes through to C so that it can
call both. We failed to do this, missing an argument entirely when
calling the C code.
Instead of trying to allocate a new instance index, we opt to store
instance indexes in trait structs (assuming there is one) and then
reuse the one in the constructed object.
Matt Corallo [Sat, 3 Sep 2022 20:24:10 +0000 (20:24 +0000)]
[TS+Java] Ensure we don't try to add a reference from `null`.
At least in `Event::PaymentPathFailed` if we try to map an event
with no `retry` we'll hit a `NullPointerException` as we'll try to
add a reference from the `null` retry back to the `Event` itself.
The simple fix is to simply exhaustively check for `null` before
adding references everywhere.
Matt Corallo [Sat, 13 Aug 2022 01:34:03 +0000 (01:34 +0000)]
Drop clone on tuple-field-fetching
Early in the lifetime of the bindings here tuple-field-fetching
had memory tracking issues which appear to have been solved now.
Thus, we can go ahead and drop the clone, at least for has-inner
types.
Matt Corallo [Fri, 12 Aug 2022 23:08:17 +0000 (23:08 +0000)]
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.
Matt Corallo [Thu, 11 Aug 2022 21:38:05 +0000 (21:38 +0000)]
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.
Matt Corallo [Thu, 28 Jul 2022 03:29:27 +0000 (03:29 +0000)]
[Java] Fix undefined behavior in HumanObjectPeerTest
CI somehow convinced the access to custom_messages_to_send to
trigger an `ArrayIndexOutOfBoundsException`, which should not be
possible except in race cases due to threading issues. Adding the
missing synchronized block should address it.
Matt Corallo [Tue, 5 Jul 2022 18:18:54 +0000 (18:18 +0000)]
[TS] Properly export unitary enums such that they're in *.d.mjs
Because the `ts/enums/*` files simply re-export from `bindings.mts`
rather than defining the enum from scratch, we have to include docs
and cannot use /* @internal */ on the `bindings.mts` unitary enums.
Matt Corallo [Thu, 30 Jun 2022 04:19:13 +0000 (04:19 +0000)]
[TS] Split C -> JS function calls based on u32/u64 parameters/return
We were calling all C -> JS functions with u32 parameters and
return types. This is fine for all of our pointers, as well as any
smaller types - u32 always gets mapped to a JavaScript `number`, so
its all consistent.
However, for u64 parameters/returns, we map the values to
JavaScript `bigint`s, which are not compatible with `numbers`, and
the correct type is checked at the FFI when returning or when users
ultimately try to use a passed `bigint` as if it were a `number`.
Thus, we have to split the `js_invoke_function` family by the
parameters and return values, using `u` for u32s and `b` for u64s
to do so.
Matt Corallo [Mon, 27 Jun 2022 19:36:44 +0000 (19:36 +0000)]
[Java] Update batteries and tests to 0.0.108
This is mostly pretty obvious changes to keep up with the latest
API, though it also includes a change to make `PeerTest` work
correctly in a world where `PeerManager` supports multithreaded
parallel access.
Matt Corallo [Mon, 27 Jun 2022 18:20:45 +0000 (18:20 +0000)]
Use fully-qualified types more often in conversions
This ensures to-human conversions still work correctly inside
enums where there is an enum variant named identically to the type
which is being converted to (eg in the new `GraphSyncError` enum).
Matt Corallo [Fri, 15 Apr 2022 18:50:15 +0000 (18:50 +0000)]
[Java] Correct trivial race condition in HumanObjectPeerTest
On my (very slow) old armv7 device, HumanObjectPeerTest can fail as
`maybe_exchange_peer_messages` will set `ran = false` *after* a
message is added to the runqueue, but before it runs, then when we
call `process_events` there will be no events to process, then
before we get into the `runqueue` `synchronized` block the message
will be delivered, causing us to think we're done, even though
there are now events pending. Because going around the loop twice
is free, we should just not set `ran` to false at the top of
`maybe_exchange_peer_messages`.