Commit graph

22 commits

Author SHA1 Message Date
Matt Corallo
d169966f76 [bindings] Update eq/clone trait fns to take object, not this_arg
When a trait is required to implement eq/clone (eg in the case of
`SocketDescriptor`), the generated trait struct contains an
eq/clone function which takes a `this_arg` pointer. Since the trait
object can always be read to get the `this_arg` pointer, there is
no loss of generality to pass the trait object itself, and it
provides a bit more flexibility when the trait could be one of
several implementations (which we use in the Java higher-level
bindings).
2020-11-23 11:08:34 -05:00
Matt Corallo
0362972d37 [bindings] Expose a _clone fn for every enum
This somewhat assumes that every public enum implements clone in
some way, but that is currently the case.
2020-11-23 11:08:34 -05:00
Matt Corallo
29b209ceea [bindings] Expose a _clone fn for every struct that derive(Clone)s 2020-11-23 11:08:34 -05:00
Matt Corallo
304471b1c1 [bindings] Support traits with generic arguments (to support #681)
Previously we'd ignored generic arguments in traits, leading to
bogus code generation after the Persister trait was added in #681.

This adds minimal support for it, fixing code generation on latest
upstream.
2020-11-23 11:08:34 -05:00
Matt Corallo
2d0cdbd33e [bindings] Un-Box Tuple mapping
Because the C++ wrappers require being able to memset(0) the C
structs to skip free(), we'd previously mapped tuples with two
pointer indirections. However, because all other types already
support memset(0)'ing to disable free() logic, we can skip the
pointer indirections and the behavior is still correct.
2020-10-21 14:54:51 -04:00
Matt Corallo
65884fffee [bindings] Fix typo in opaque struct docs found by Val 2020-10-21 14:54:51 -04:00
Matt Corallo
e12215ca8a [bindings] Use the same SipHash keys to make C++ header stable 2020-10-21 14:54:51 -04:00
Matt Corallo
35e48cf479 [bindings] Use enum to describe deref'ing needed for Option<> inners 2020-10-21 14:54:51 -04:00
Matt Corallo
6df3aa76c3 [bindings] Drop one static-lifetime restriction and check success
In general we should stop enforcing that all lifetimes are static
- we may take references from C and its up to reviewing the diff on
the bindings changes and the user(s) to ensure lifetimes are valid.

Also asserts a success criteria that was missed before.
2020-10-21 14:50:22 -04:00
Matt Corallo
4d0cf680ab [bindings] Handle type X = Y aliasing in type resolution
For non-generic type aliases which are meant as convinient aliases
for more complex types, we need to store the aliased type (with all
paths made absolute) and use that in type resolution.

The most code by far is just making all the paths in a type absolute
but its not too bad either.
2020-10-21 14:50:22 -04:00
Matt Corallo
00fb152758 [bindings] Handle ::-prefixed paths in a few places 2020-10-21 14:50:22 -04:00
Matt Corallo
eb7faa85e4 [bindings] Remove some uneccessary no-multi-ident path restrictions 2020-10-21 14:50:22 -04:00
Matt Corallo
bb4115effd [bindings] Avoid guessing whether resolved type is a ref in blocks
In some cases, things which are a Rust Reference (ie slices), we
may still want to map them as a non-reference and need to put a
"mut " in front of the variable name in a function decl. This
worked fine by just checking for the slice case, except that we
are about to add support for type aliases, which no longer match
the naive case.

Instead, we can just have the types module print out the C type and
check if it begins with a '&' to figure out if it is a reference.
2020-10-21 14:50:22 -04:00
Matt Corallo
a14e63e0b3 [bindings] Support mapping slices which contain tuples (with refs)
New work upstream puts tuples in slices, which is a very reasonable
thing to expect, however we don't know how to generate conversions
for such objects. Making it more complicated, upstream changes also
include references to things inside such slices, which requires
special handling to avoid creating dangling references.

This adds support for converting such objects, noting that slices
need to be converted first into Vecs which own their underlying
objects and then need to map any reference types into references.
2020-10-21 14:50:22 -04:00
Matt Corallo
d9a38d1846 [bindings] Give Transaction objects a buffer-is-owned flag.
A lot of our container mapping depends on the `is_owned` flag
which we have for in-crate mapped objects to map references and
non-references into the same container type. Transaction was
mapped to two completely different types (a slice and a Vec type),
which led to a number of edge cases in the bindings generation.
Specifically, I spent a few days trying to map
`[(A, &Transaction)]` properly and came up empty - we map slices
into the same types as Vecs (and rely on the `is_owned` flag to
avoid double-free) and the lack of one for `Transaction` would have
required a special-case in numerous functions.

Instead, we just add a flag in `Transaction` to mirror what we do
for in-crate types and check it before free-ing any underlying
memory.

Note that, sadly, because the c_types objects aren't mapped as a
part of our C++ bindings generation, you have to manually call
`Transaction_free()` even in C++.
2020-10-21 14:50:22 -04:00
Matt Corallo
0719f9af00 [bindings] Add support for Option<T> where T is a mapped trait
When mapping an `Option<T>` where T is a mapped trait, we need to
move out of the `*mut T`, however the current generation results in
a `*const T` and a conversion that just takes a reference to the
pointed-to object. This is because the only place this code was
previously used was for slices, which *do* need a reference.

Additionally, we need to know how to convert `Option` containers
which do not contain an opaque type.

Sadly, the easiest way to get the desired result is to add another
special case in container mapping, keeping the current behavior for
slices, but moving out of the pointed-to object for other types.
2020-10-12 12:17:26 -04:00
Matt Corallo
a1d0dde507 [bindings] Use == null() instead of is_null() to avoid ambiguity
When we have a `Trait` wrapped as an `Option<Trait>`, we called
`<*const Trait>.is_null()` which resulted in rustc trying to take
the most braindead option of dereferencing the whole thing and
hitting a recursive dereference since we
`impl Deref<Target=Trait> for Trait` for all our traits.

Instead, we can be explicit and just compare the pointer directly
with `std::ptr::null()` which avoids this.
2020-10-12 12:17:26 -04:00
Matt Corallo
fe279c4034 [bindings] Include a GenericTypes context in more places
A few places got a None in the previous commit to avoid increasing
the diff size. However, it makes sense to have GenericTypes contexts
there, so we pipe them through the neccessary places.
2020-10-12 12:17:26 -04:00
Matt Corallo
8a2513f84b [bindings] Push generic resolution into resolve_path
Like the previous commit pushing into maybe_resolve_path, this
makes generic resolution a part of type resolution everywhere.
2020-10-12 12:17:26 -04:00
Matt Corallo
b7f7aba2e7 [bindings] Push generic resolution into maybe_resolve_path
This pushes down the logic to check if a given Path is, in fact,
a reference to a generic into the common maybe_resolve_path instead
of doing it redundantly in a few different places. Net loss of LoC.
2020-10-12 12:17:26 -04:00
Matt Corallo
16b9309e7c Support use ident; in bindings
Somehow we'd never had any cases of it and it requires an extra
(trivial) match arm.
2020-10-12 12:17:26 -04:00
Matt Corallo
48e8678a9a Add tool to read a Rust crate and generate C-compatible wrappers
In general, it maps:
 * Traits to a struct with a void* and a list of function pointers,
   emulating what the compiler will do for a dyn trait anyway,
 * Structs as a struct with a single opaque pointer to the
   underlying type and a flag to indicate ownership. While this is
   a bit less effecient than just a direct pointer, it neatly lets
   us expose in the public interface the concept of ownership by
   setting a flag in the generated struct.
 * Unit enums as enums with each type copied over and conversion
   functions,
 * Non-unit enums have each field converted back and forth with a
   type flag and a union across all the C-mapped fields.
2020-09-10 21:58:44 -04:00