diff --git a/lix/libexpr/value.cc b/lix/libexpr/value.cc index 868692355..a875e6c79 100644 --- a/lix/libexpr/value.cc +++ b/lix/libexpr/value.cc @@ -2,6 +2,7 @@ #include +#include "libexpr/gc-alloc.hh" #include "lix/libexpr/eval.hh" #include "lix/libexpr/print.hh" @@ -27,15 +28,18 @@ static_assert(alignof(Value::PrimOp) >= Value::Acb::TAG_ALIGN); static_assert(alignof(Value::Int) >= Value::Acb::TAG_ALIGN); static_assert(alignof(Value::Lambda) >= Value::Acb::TAG_ALIGN); -static void copyContextToValue(Value::String & s, const NixStringContext & context) +static char const ** copyContext(const NixStringContext & context) { - if (!context.empty()) { - size_t n = 0; - s.context = gcAllocType(context.size() + 1); - for (auto & i : context) - s.context[n++] = gcCopyStringIfNeeded(i.to_string()); - s.context[n] = 0; + if (context.empty()) { + return nullptr; } + auto contextPtr = gcAllocType(context.size() + 1); + size_t n = 0; + for (auto & i : context) { + contextPtr[n++] = gcCopyStringIfNeeded(i.to_string()); + } + contextPtr[n] = nullptr; + return contextPtr; } Value::Value(attrs_t, BindingsBuilder & bindings) : Value(NewValueAs::attrs, bindings.finish()) {} @@ -62,11 +66,13 @@ void Value::mkPrimOp(PrimOp * p) } Value::Value(string_t, Str * s, const NixStringContext & context) + : Value(NewValueAs::string, s, copyContext(context)) +{ +} + +Value::Value(string_t, std::string_view s, const NixStringContext & context) + : Value(NewValueAs::string, s, copyContext(context)) { - auto block = gcAllocType(); - *block = {.content = s, .context = nullptr}; - raw = tag(tString, block); - copyContextToValue(*block, context); } #ifndef __APPLE__ diff --git a/lix/libexpr/value.hh b/lix/libexpr/value.hh index 52dc94138..2c8349690 100644 --- a/lix/libexpr/value.hh +++ b/lix/libexpr/value.hh @@ -475,29 +475,7 @@ public: /// /// The string data *is* copied from @ref copyFrom, and this constructor /// performs a dynamic (GC) allocation to do so. - Value(string_t, std::string_view copyFrom, NixStringContext const & context = {}) - { - auto block = gcAllocType(); - *block = {.content = Str::gcCopy(copyFrom), .context = nullptr}; - raw = tag(tString, block); - - if (context.empty()) { - // It stays nullptr. - return; - } - - // Copy the context. - block->context = gcAllocType(context.size() + 1); - - size_t n = 0; - for (NixStringContextElem const & contextElem : context) { - block->context[n] = gcCopyStringIfNeeded(contextElem.to_string()); - n += 1; - } - - // Terminator sentinel. - block->context[n] = nullptr; - } + Value(string_t, std::string_view copyFrom, NixStringContext const & context = {}); /// Constructs a nix language value of type "path", with the value of the /// C-string pointed to by @ref strPtr.