diff options
author | Kane York <kanepyork@gmail.com> | 2020-07-31T22·05-0700 |
---|---|---|
committer | kanepyork <rikingcoding@gmail.com> | 2020-08-01T18·54+0000 |
commit | dc4c0bad65be85c60b2d077eab2e1618d1ee7d5a (patch) | |
tree | c8ad24820f69d5aaed18487efa788e8da0855e1d /third_party/nix/src/libexpr/eval.cc | |
parent | be8c8836737983d900a0743605ab4da2001898d7 (diff) |
chore(3p/nix/libexpr): Cleanups and notes in eval.cc r/1525
Add two more garbage-collection flags. Annotate how terrible tExternal is. Prepare to fix the smuggle casting in ExprWith. Add a static_cast. Change-Id: I20f980abc8cb192e094f539185900a6df5457c29 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1503 Tested-by: BuildkiteCI Reviewed-by: glittershark <grfn@gws.fyi> Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'third_party/nix/src/libexpr/eval.cc')
-rw-r--r-- | third_party/nix/src/libexpr/eval.cc | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/third_party/nix/src/libexpr/eval.cc b/third_party/nix/src/libexpr/eval.cc index a762571fca2d..3d134be19e29 100644 --- a/third_party/nix/src/libexpr/eval.cc +++ b/third_party/nix/src/libexpr/eval.cc @@ -12,6 +12,7 @@ #define GC_INCLUDE_NEW +#include <absl/container/flat_hash_set.h> #include <absl/strings/match.h> #include <gc/gc.h> #include <gc/gc_cpp.h> @@ -482,8 +483,9 @@ Value* EvalState::addPrimOp(const std::string& name, size_t arity, std::string name2 = std::string(name, 0, 2) == "__" ? std::string(name, 2) : name; Symbol sym = symbols.Create(name2); + // Even though PrimOp doesn't need tracing, it needs to be collected. v->type = tPrimOp; - v->primOp = new PrimOp(primOp, arity, sym); + v->primOp = new (GC) PrimOp(primOp, arity, sym); staticBaseEnv.vars[symbols.Create(name)] = baseEnvDispl; baseEnv.values[baseEnvDispl++] = v; baseEnv.values[0]->attrs->push_back(Attr(sym, v)); @@ -599,6 +601,7 @@ inline Value* EvalState::lookupVar(Env* env, const ExprVar& var, bool noEval) { return nullptr; } Value* v = allocValue(); + // TODO(kanepyork): Here's the other end of the cast smuggle. evalAttrs(*env->up, reinterpret_cast<Expr*>(env->values[0]), *v); env->values[0] = v; env->type = Env::HasWithAttrs; @@ -1333,8 +1336,14 @@ void ExprPos::eval(EvalState& state, Env& env, Value& v) { state.mkPos(v, &pos); } +template <typename T> +using traceable_flat_hash_set = + absl::flat_hash_set<T, absl::container_internal::hash_default_hash<T>, + absl::container_internal::hash_default_eq<T>, + traceable_allocator<T>>; + void EvalState::forceValueDeep(Value& v) { - std::set<const Value*> seen; + traceable_flat_hash_set<const Value*> seen; std::function<void(Value & v)> recurse; @@ -1378,7 +1387,7 @@ NixInt EvalState::forceInt(Value& v, const Pos& pos) { NixFloat EvalState::forceFloat(Value& v, const Pos& pos) { forceValue(v, pos); if (v.type == tInt) { - return v.integer; + return static_cast<NixFloat>(v.integer); } if (v.type != tFloat) { throwTypeError("value is %1% while a float was expected, at %2%", v, pos); @@ -1814,6 +1823,9 @@ void EvalState::printStats() { } size_t valueSize(Value& v) { + // Can't convert to flat_hash_set because of tExternal + // Can't set the allocator because of tExternal + // The GC is likely crying over this std::set<const void*> seen; auto doString = [&](const char* s) -> size_t { @@ -1884,6 +1896,7 @@ size_t valueSize(Value& v) { break; } seen.insert(v.external); + // note: this is a plugin call sz += v.external->valueSize(seen); break; default:; |