Extend Rust FFI

Do idiomatic C++ copy and move constructors for a few things, so
wrapping structs' defaults can work.
This commit is contained in:
John Ericson 2020-03-22 23:43:07 -04:00 committed by John Ericson
parent eb1911e277
commit e433d4af4c
8 changed files with 63 additions and 21 deletions

View file

@ -64,6 +64,13 @@ pub extern "C" fn ffi_StorePath_clone(self_: &StorePath) -> StorePath {
self_.clone() 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] #[no_mangle]
pub extern "C" fn ffi_StorePath_name(self_: &StorePath) -> &str { pub extern "C" fn ffi_StorePath_name(self_: &StorePath) -> &str {
self_.name.name() self_.name.name()

View file

@ -22,6 +22,9 @@ struct DerivationOutput
, hashAlgo(std::move(hashAlgo)) , hashAlgo(std::move(hashAlgo))
, hash(std::move(hash)) , hash(std::move(hash))
{ } { }
DerivationOutput(const DerivationOutput &) = default;
DerivationOutput(DerivationOutput &&) = default;
DerivationOutput & operator = (const DerivationOutput &) = default;
void parseHashInfo(bool & recursive, Hash & hash) const; void parseHashInfo(bool & recursive, Hash & hash) const;
}; };

View file

@ -4,7 +4,7 @@
namespace nix { namespace nix {
NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence) 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 = [&]() { auto corrupt = [&]() {
throw Error(format("NAR info file '%1%' is corrupt") % whence); throw Error(format("NAR info file '%1%' is corrupt") % whence);

View file

@ -13,6 +13,7 @@ extern "C" {
void ffi_StorePath_drop(void *); void ffi_StorePath_drop(void *);
bool ffi_StorePath_less_than(const StorePath & a, const StorePath & b); bool ffi_StorePath_less_than(const StorePath & a, const StorePath & b);
bool ffi_StorePath_eq(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); unsigned char * ffi_StorePath_hash_data(const StorePath & p);
} }
@ -43,6 +44,19 @@ struct StorePath : rust::Value<3 * sizeof(void *) + 24, ffi_StorePath_drop>
return !(*this == other); 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; StorePath clone() const;
/* Check whether a file name ends with the extension for /* Check whether a file name ends with the extension for

View file

@ -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::optional<ValidPathInfo> decodeValidPathInfo(const Store & store, std::istream & str, bool hashGiven)
{ {
std::string path; std::string path;

View file

@ -189,8 +189,9 @@ struct ValidPathInfo
Strings shortRefs() const; Strings shortRefs() const;
ValidPathInfo(StorePath && path) : path(std::move(path)) { } ValidPathInfo(StorePath && path) : path(std::move(path)) { };
explicit ValidPathInfo(const ValidPathInfo & other); ValidPathInfo(const StorePath & path) : path(path) { };
ValidPathInfo(const ValidPathInfo & other) = default;
virtual ~ValidPathInfo() { } virtual ~ValidPathInfo() { }
}; };

View file

@ -44,6 +44,12 @@ struct Hash
string. */ string. */
Hash(const std::string & s, HashType type = htUnknown); Hash(const std::string & s, HashType type = htUnknown);
Hash(const Hash &) = default;
Hash(Hash &&) = default;
Hash & operator = (const Hash &) = default;
void init(); void init();
/* Check whether a hash is set. */ /* Check whether a hash is set. */

View file

@ -30,7 +30,10 @@ protected:
// Must not be called directly. // Must not be called directly.
Value() Value()
{ } {
// Precaution, in case this is used improperly
evacuate();
}
Value(Value && other) Value(Value && other)
: raw(other.raw) : raw(other.raw)
@ -38,6 +41,19 @@ protected:
other.evacuate(); other.evacuate();
} }
// Not all Rust types are Clone / Copy, but our base Value class needs to
// have a copy constructor so that ones which do implement Copy/Clone
// can be copied/cloned.
Value(const Value & other)
: raw(other.raw)
{
}
void operator =(const Value & other)
{
if (!isEvacuated())
drop(this);
}
void operator =(Value && other) void operator =(Value && other)
{ {
if (!isEvacuated()) if (!isEvacuated())
@ -76,6 +92,16 @@ struct Vec : Value<3 * sizeof(void *), drop>
{ {
return ((const T * *) &this->raw)[0]; 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. */ /* A Rust slice. */
@ -144,7 +170,7 @@ struct Result
std::exception_ptr * exc; std::exception_ptr * exc;
}; };
Result() : tag(Uninit) { }; // FIXME: remove Result() = delete;
Result(const Result &) = delete; Result(const Result &) = delete;
@ -171,7 +197,7 @@ struct Result
} }
/* Rethrow the wrapped exception or return the wrapped value. */ /* Rethrow the wrapped exception or return the wrapped value. */
T unwrap() T unwrap() &&
{ {
if (tag == Ok) { if (tag == Ok) {
tag = Uninit; tag = Uninit;