diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-04-16 18:33:10 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-04-16 18:33:10 +0200 |
commit | f89349f07eda66dea2aa3b70bdc2c5c649406bdc (patch) | |
tree | 9ff9148956592d29fc1c7e45ccf4dfc64b2457b5 /src/libexpr | |
parent | 0858738355dd9bdb20a723f15629c423fe14a7b1 (diff) | |
parent | efaffaa9d1de38efecb718aa7a99ba1f2e342ade (diff) |
Merge remote-tracking branch 'origin/master' into flakes
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 8 | ||||
-rw-r--r-- | src/libexpr/json-to-value.cc | 63 | ||||
-rw-r--r-- | src/libexpr/primops.cc | 10 | ||||
-rw-r--r-- | src/libexpr/primops/fetchMercurial.cc | 15 | ||||
-rw-r--r-- | src/libexpr/value.hh | 9 |
5 files changed, 58 insertions, 47 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index c5945adf0..83be997e9 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -23,6 +23,8 @@ #if HAVE_BOEHMGC +#define GC_INCLUDE_NEW + #include <gc/gc.h> #include <gc/gc_cpp.h> @@ -57,6 +59,12 @@ static char * dupStringWithLen(const char * s, size_t size) } +RootValue allocRootValue(Value * v) +{ + return std::allocate_shared<Value *>(traceable_allocator<Value *>(), v); +} + + static void printValue(std::ostream & str, std::set<const Value *> & active, const Value & v) { checkInterrupt(); diff --git a/src/libexpr/json-to-value.cc b/src/libexpr/json-to-value.cc index 1fdce1983..76e1a26bf 100644 --- a/src/libexpr/json-to-value.cc +++ b/src/libexpr/json-to-value.cc @@ -4,7 +4,6 @@ #include <nlohmann/json.hpp> using json = nlohmann::json; -using std::unique_ptr; namespace nix { @@ -13,69 +12,69 @@ namespace nix { class JSONSax : nlohmann::json_sax<json> { class JSONState { protected: - unique_ptr<JSONState> parent; - Value * v; + std::unique_ptr<JSONState> parent; + RootValue v; public: - virtual unique_ptr<JSONState> resolve(EvalState &) + virtual std::unique_ptr<JSONState> resolve(EvalState &) { throw std::logic_error("tried to close toplevel json parser state"); - }; - explicit JSONState(unique_ptr<JSONState>&& p) : parent(std::move(p)), v(nullptr) {}; - explicit JSONState(Value* v) : v(v) {}; - JSONState(JSONState& p) = delete; - Value& value(EvalState & state) + } + explicit JSONState(std::unique_ptr<JSONState> && p) : parent(std::move(p)) {} + explicit JSONState(Value * v) : v(allocRootValue(v)) {} + JSONState(JSONState & p) = delete; + Value & value(EvalState & state) { - if (v == nullptr) - v = state.allocValue(); - return *v; - }; - virtual ~JSONState() {}; - virtual void add() {}; + if (!v) + v = allocRootValue(state.allocValue()); + return **v; + } + virtual ~JSONState() {} + virtual void add() {} }; class JSONObjectState : public JSONState { using JSONState::JSONState; - ValueMap attrs = ValueMap(); - virtual unique_ptr<JSONState> resolve(EvalState & state) override + ValueMap attrs; + std::unique_ptr<JSONState> resolve(EvalState & state) override { - Value& v = parent->value(state); + Value & v = parent->value(state); state.mkAttrs(v, attrs.size()); for (auto & i : attrs) v.attrs->push_back(Attr(i.first, i.second)); return std::move(parent); } - virtual void add() override { v = nullptr; }; + void add() override { v = nullptr; } public: - void key(string_t& name, EvalState & state) + void key(string_t & name, EvalState & state) { - attrs[state.symbols.create(name)] = &value(state); + attrs.insert_or_assign(state.symbols.create(name), &value(state)); } }; class JSONListState : public JSONState { - ValueVector values = ValueVector(); - virtual unique_ptr<JSONState> resolve(EvalState & state) override + ValueVector values; + std::unique_ptr<JSONState> resolve(EvalState & state) override { - Value& v = parent->value(state); + Value & v = parent->value(state); state.mkList(v, values.size()); for (size_t n = 0; n < values.size(); ++n) { v.listElems()[n] = values[n]; } return std::move(parent); } - virtual void add() override { - values.push_back(v); + void add() override { + values.push_back(*v); v = nullptr; - }; + } public: - JSONListState(unique_ptr<JSONState>&& p, std::size_t reserve) : JSONState(std::move(p)) + JSONListState(std::unique_ptr<JSONState> && p, std::size_t reserve) : JSONState(std::move(p)) { values.reserve(reserve); } }; EvalState & state; - unique_ptr<JSONState> rs; + std::unique_ptr<JSONState> rs; template<typename T, typename... Args> inline bool handle_value(T f, Args... args) { @@ -107,12 +106,12 @@ public: return handle_value(mkInt, val); } - bool number_float(number_float_t val, const string_t& s) + bool number_float(number_float_t val, const string_t & s) { return handle_value(mkFloat, val); } - bool string(string_t& val) + bool string(string_t & val) { return handle_value<void(Value&, const char*)>(mkString, val.c_str()); } @@ -123,7 +122,7 @@ public: return true; } - bool key(string_t& name) + bool key(string_t & name) { dynamic_cast<JSONObjectState*>(rs.get())->key(name, state); return true; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 08a1adf3b..6be88e6fd 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -122,16 +122,16 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args } w.attrs->sort(); - static Value * fun = nullptr; + static RootValue fun; if (!fun) { - fun = state.allocValue(); + fun = allocRootValue(state.allocValue()); state.eval(state.parseExprFromString( #include "imported-drv-to-derivation.nix.gen.hh" - , "/"), *fun); + , "/"), **fun); } - state.forceFunction(*fun, pos); - mkApp(v, *fun, w); + state.forceFunction(**fun, pos); + mkApp(v, **fun, w); state.forceAttrs(v, pos); } else { state.forceAttrs(*args[0]); diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index f18351646..0a1ba49d5 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -54,15 +54,14 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar if (evalSettings.pureEval && !rev) throw Error("in pure evaluation mode, 'fetchMercurial' requires a Mercurial revision"); - auto parsedUrl = parseURL( - url.find("://") != std::string::npos - ? "hg+" + url - : "hg+file://" + url); - if (rev) parsedUrl.query.insert_or_assign("rev", rev->gitRev()); - if (ref) parsedUrl.query.insert_or_assign("ref", *ref); - // FIXME: use name - auto input = fetchers::inputFromURL(parsedUrl); + fetchers::Attrs attrs; + attrs.insert_or_assign("type", "hg"); + attrs.insert_or_assign("url", url.find("://") != std::string::npos ? url : "file://" + url); + if (ref) attrs.insert_or_assign("ref", *ref); + if (rev) attrs.insert_or_assign("rev", rev->gitRev()); + auto input = fetchers::inputFromAttrs(attrs); + // FIXME: use name auto [tree, input2] = input->fetchTree(state.store); state.mkAttrs(v, 8); diff --git a/src/libexpr/value.hh b/src/libexpr/value.hh index 60de60c67..1a0738241 100644 --- a/src/libexpr/value.hh +++ b/src/libexpr/value.hh @@ -258,12 +258,17 @@ void mkPath(Value & v, const char * s); #if HAVE_BOEHMGC -typedef std::vector<Value *, gc_allocator<Value *> > ValueVector; -typedef std::map<Symbol, Value *, std::less<Symbol>, gc_allocator<std::pair<const Symbol, Value *> > > ValueMap; +typedef std::vector<Value *, traceable_allocator<Value *> > ValueVector; +typedef std::map<Symbol, Value *, std::less<Symbol>, traceable_allocator<std::pair<const Symbol, Value *> > > ValueMap; #else typedef std::vector<Value *> ValueVector; typedef std::map<Symbol, Value *> ValueMap; #endif +/* A value allocated in traceable memory. */ +typedef std::shared_ptr<Value *> RootValue; + +RootValue allocRootValue(Value * v); + } |