Skip to content

Commit

Permalink
Extend Rust FFI
Browse files Browse the repository at this point in the history
Do ideomatic C++ copy and move constructors for a few things, so
wrapping structs' defaults can work.
  • Loading branch information
Ericson2314 committed Mar 25, 2020
1 parent 0a10854 commit 233e672
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 21 deletions.
7 changes: 7 additions & 0 deletions nix-rust/src/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ pub extern "C" fn ffi_StorePath_clone(self_: &StorePath) -> StorePath {
self_.clone()
}

#[no_mangle]
pub extern "C" fn ffi_StorePath_clone_to(self_: &StorePath, other: *mut StorePath) {
unsafe {
core::ptr::write(other, self_.clone());
}
}

#[no_mangle]
pub extern "C" fn ffi_StorePath_name(self_: &StorePath) -> &str {
self_.name.name()
Expand Down
3 changes: 3 additions & 0 deletions src/libstore/derivations.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ struct DerivationOutput
, hashAlgo(std::move(hashAlgo))
, hash(std::move(hash))
{ }
DerivationOutput(const DerivationOutput &) = default;
DerivationOutput(DerivationOutput &&) = default;
DerivationOutput & operator = (const DerivationOutput &) = default;
void parseHashInfo(bool & recursive, Hash & hash) const;
};

Expand Down
2 changes: 1 addition & 1 deletion src/libstore/nar-info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace nix {

NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
: ValidPathInfo(StorePath::dummy.clone()) // FIXME: hack
: ValidPathInfo(StorePath::dummy) // FIXME: hack
{
auto corrupt = [&]() {
throw Error(format("NAR info file '%1%' is corrupt") % whence);
Expand Down
14 changes: 14 additions & 0 deletions src/libstore/path.hh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ extern "C" {
void ffi_StorePath_drop(void *);
bool ffi_StorePath_less_than(const StorePath & a, const StorePath & b);
bool ffi_StorePath_eq(const StorePath & a, const StorePath & b);
void ffi_StorePath_clone_to(const StorePath & _other, StorePath & _this);
unsigned char * ffi_StorePath_hash_data(const StorePath & p);
}

Expand Down Expand Up @@ -43,6 +44,19 @@ struct StorePath : rust::Value<3 * sizeof(void *) + 24, ffi_StorePath_drop>
return !(*this == other);
}

StorePath(StorePath && that) = default;

StorePath(const StorePath & that)
{
ffi_StorePath_clone_to(that, *this);
}

void operator = (const StorePath & that)
{
(rust::Value<3 * sizeof(void *) + 24, ffi_StorePath_drop>::operator = (that));
ffi_StorePath_clone_to(that, *this);
}

StorePath clone() const;

/* Check whether a file name ends with the extension for
Expand Down
15 changes: 0 additions & 15 deletions src/libstore/store-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -687,21 +687,6 @@ void copyClosure(ref<Store> srcStore, ref<Store> dstStore,
}


ValidPathInfo::ValidPathInfo(const ValidPathInfo & other)
: path(other.path.clone())
, deriver(other.deriver ? other.deriver->clone(): std::optional<StorePath>{})
, narHash(other.narHash)
, references(cloneStorePathSet(other.references))
, registrationTime(other.registrationTime)
, narSize(other.narSize)
, id(other.id)
, ultimate(other.ultimate)
, sigs(other.sigs)
, ca(other.ca)
{
}


std::optional<ValidPathInfo> decodeValidPathInfo(const Store & store, std::istream & str, bool hashGiven)
{
std::string path;
Expand Down
5 changes: 3 additions & 2 deletions src/libstore/store-api.hh
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ struct ValidPathInfo

Strings shortRefs() const;

ValidPathInfo(StorePath && path) : path(std::move(path)) { }
explicit ValidPathInfo(const ValidPathInfo & other);
ValidPathInfo(StorePath && path) : path(std::move(path)) { };
ValidPathInfo(const StorePath & path) : path(path) { };
ValidPathInfo(const ValidPathInfo & other) = default;

virtual ~ValidPathInfo() { }
};
Expand Down
6 changes: 6 additions & 0 deletions src/libutil/hash.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ struct Hash
string. */
Hash(const std::string & s, HashType type = htUnknown);

Hash(const Hash &) = default;

Hash(Hash &&) = default;

Hash & operator = (const Hash &) = default;

void init();

/* Check whether a hash is set. */
Expand Down
31 changes: 28 additions & 3 deletions src/libutil/rust-ffi.hh
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,29 @@ protected:

// Must not be called directly.
Value()
{ }
{
// Precaution, in case this is used improperly
evacuate();
}

Value(Value && other)
: raw(other.raw)
{
other.evacuate();
}

// Not all Rust types are Clone / Copy, but our base "value" class needs to
// have a copy constructor so the ones that are can be.
Value(const Value & other)
: raw(other.raw)
{
}
void operator =(const Value & other)
{
if (!isEvacuated())
drop(this);
}

void operator =(Value && other)
{
if (!isEvacuated())
Expand Down Expand Up @@ -76,6 +91,16 @@ struct Vec : Value<3 * sizeof(void *), drop>
{
return ((const T * *) &this->raw)[0];
}

protected:

// Must not be called directly.
Vec<T, drop>();

Vec<T, drop>(Vec<T, drop> && other) = default;

// Delete until we know how to do this properly.
Vec<T, drop>(const Vec<T, drop> & other) = delete;
};

/* A Rust slice. */
Expand Down Expand Up @@ -144,7 +169,7 @@ struct Result
std::exception_ptr * exc;
};

Result() : tag(Uninit) { }; // FIXME: remove
Result() = delete;

Result(const Result &) = delete;

Expand All @@ -171,7 +196,7 @@ struct Result
}

/* Rethrow the wrapped exception or return the wrapped value. */
T unwrap()
T unwrap() &&
{
if (tag == Ok) {
tag = Uninit;
Expand Down

0 comments on commit 233e672

Please sign in to comment.