From 3e46fbc655421f1d40d0984d701925e81937402d Mon Sep 17 00:00:00 2001 From: dragonmux Date: Wed, 3 Jan 2024 15:07:22 +0000 Subject: [PATCH] rust: Reworked the unwrap helpers by effectively hiding the crime of memcpy()'ing into a non-POD type from the compiler There is still the possibility that this can explode horribly, but the result should be the same codegen and fixes the warning This also makes the helpers `inline` so they'll usually be compiled out for a nice speed boost --- rust/rust.cc | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/rust/rust.cc b/rust/rust.cc index 23286a68..279884d0 100644 --- a/rust/rust.cc +++ b/rust/rust.cc @@ -16,6 +16,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include "log.h" #include "nextpnr.h" @@ -33,28 +34,30 @@ namespace { memcpy(&b, &thing, sizeof(T)); return b; } - - BelId unwrap_bel(uint64_t bel) { - static_assert(sizeof(BelId) <= 8, "T is too big for FFI"); - auto b = BelId(); - memcpy(&b, &bel, sizeof(BelId)); - return b; - } - - PipId unwrap_pip(uint64_t pip) { - static_assert(sizeof(PipId) <= 8, "T is too big for FFI"); - auto p = PipId(); - memcpy(&p, &pip, sizeof(PipId)); - return p; - } - - WireId unwrap_wire(uint64_t wire) { - static_assert(sizeof(WireId) <= 8, "T is too big for FFI"); - auto w = WireId(); - memcpy(&w, &wire, sizeof(WireId)); - return w; - } #pragma GCC diagnostic pop + + template static inline T unwrap(const std::array &value) noexcept { + static_assert(sizeof(T) <= 8, "T is too big for FFI"); + T result{}; + memcpy(&result, value.data(), sizeof(result)); + return result; + } + + template static inline T unwrap(const uint64_t value) noexcept { + std::array data{}; + static_assert(sizeof(value) >= data.size(), "uint64_t is not an appropriate size"); + memcpy(data.data(), &value, data.size()); + return unwrap(data); + } + + static inline BelId unwrap_bel(const uint64_t bel) noexcept + { return unwrap(bel); } + + static inline PipId unwrap_pip(const uint64_t pip) noexcept + { return unwrap(pip); } + + static inline WireId unwrap_wire(const uint64_t wire) noexcept + { return unwrap(wire); } } using DownhillIter = decltype(Context(ArchArgs()).getPipsDownhill(WireId()).begin());