irc/evaluator: fix e passed by value in Thunk constructor
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: If3bdfd1fc0851d4113b89827474a74a86a6a6964
This commit is contained in:
parent
eb84d4617b
commit
63a9eddc49
1 changed files with 406 additions and 430 deletions
|
|
@ -7,8 +7,8 @@
|
|||
#include "nix/expr/value.hh"
|
||||
#include "nix/util/error.hh"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace nix_irc {
|
||||
|
||||
|
|
@ -21,9 +21,7 @@ struct IREnvironment {
|
|||
|
||||
explicit IREnvironment(IREnvironment* p = nullptr) : parent(p), with_attrs(nullptr) {}
|
||||
|
||||
void bind(Value* val) {
|
||||
bindings.push_back(val);
|
||||
}
|
||||
void bind(Value* val) { bindings.push_back(val); }
|
||||
|
||||
Value* lookup(uint32_t index) {
|
||||
IREnvironment* env = this;
|
||||
|
|
@ -58,8 +56,7 @@ struct Thunk {
|
|||
IREnvironment* env;
|
||||
bool blackholed;
|
||||
|
||||
Thunk(std::shared_ptr<Node> e, IREnvironment* en)
|
||||
: expr(e), env(en), blackholed(false) {}
|
||||
Thunk(const std::shared_ptr<Node>& e, IREnvironment* en) : expr(e), env(en), blackholed(false) {}
|
||||
};
|
||||
|
||||
struct Evaluator::Impl {
|
||||
|
|
@ -111,20 +108,15 @@ struct Evaluator::Impl {
|
|||
|
||||
if (auto* n = node->get_if<ConstIntNode>()) {
|
||||
v.mkInt(n->value);
|
||||
}
|
||||
else if (auto* n = node->get_if<ConstStringNode>()) {
|
||||
} else if (auto* n = node->get_if<ConstStringNode>()) {
|
||||
v.mkString(n->value);
|
||||
}
|
||||
else if (auto* n = node->get_if<ConstPathNode>()) {
|
||||
} else if (auto* n = node->get_if<ConstPathNode>()) {
|
||||
v.mkPath(state.rootPath(CanonPath(n->value)));
|
||||
}
|
||||
else if (auto* n = node->get_if<ConstBoolNode>()) {
|
||||
} else if (auto* n = node->get_if<ConstBoolNode>()) {
|
||||
v.mkBool(n->value);
|
||||
}
|
||||
else if (auto* n = node->get_if<ConstNullNode>()) {
|
||||
} else if (auto* n = node->get_if<ConstNullNode>()) { // NOLINT(bugprone-branch-clone)
|
||||
v.mkNull();
|
||||
}
|
||||
else if (auto* n = node->get_if<VarNode>()) {
|
||||
} else if (auto* n = node->get_if<VarNode>()) {
|
||||
Value* bound = env ? env->lookup(n->index) : nullptr;
|
||||
if (!bound && env && n->name.has_value()) {
|
||||
bound = env->lookup_with(state, n->name.value());
|
||||
|
|
@ -134,25 +126,21 @@ struct Evaluator::Impl {
|
|||
}
|
||||
force(bound);
|
||||
v = *bound;
|
||||
}
|
||||
else if (auto* n = node->get_if<LambdaNode>()) {
|
||||
} else if (auto* n = node->get_if<LambdaNode>()) {
|
||||
auto lambda_env = env;
|
||||
auto body = n->body;
|
||||
|
||||
auto primOp = [this, lambda_env, body](EvalState& state, PosIdx pos,
|
||||
Value** args, Value& result) {
|
||||
auto primOp = [this, lambda_env, body](EvalState& state, PosIdx pos, Value** args,
|
||||
Value& result) {
|
||||
auto call_env = make_env(lambda_env);
|
||||
call_env->bind(args[0]);
|
||||
eval_node(body, result, call_env);
|
||||
};
|
||||
|
||||
v.mkPrimOp(new PrimOp {
|
||||
.name = n->param_name.value_or("lambda"),
|
||||
v.mkPrimOp(new PrimOp{.name = n->param_name.value_or("lambda"),
|
||||
.arity = static_cast<size_t>(n->arity),
|
||||
.fun = primOp
|
||||
});
|
||||
}
|
||||
else if (auto* n = node->get_if<AppNode>()) {
|
||||
.fun = primOp});
|
||||
} else if (auto* n = node->get_if<AppNode>()) {
|
||||
Value* func_val = state.allocValue();
|
||||
eval_node(n->func, *func_val, env);
|
||||
force(func_val);
|
||||
|
|
@ -160,8 +148,7 @@ struct Evaluator::Impl {
|
|||
Value* arg_val = make_thunk(n->arg, env);
|
||||
|
||||
state.callFunction(*func_val, *arg_val, v, noPos);
|
||||
}
|
||||
else if (auto* n = node->get_if<BinaryOpNode>()) {
|
||||
} else if (auto* n = node->get_if<BinaryOpNode>()) {
|
||||
Value* left = state.allocValue();
|
||||
Value* right = state.allocValue();
|
||||
|
||||
|
|
@ -308,8 +295,7 @@ struct Evaluator::Impl {
|
|||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (auto* n = node->get_if<UnaryOpNode>()) {
|
||||
} else if (auto* n = node->get_if<UnaryOpNode>()) {
|
||||
Value* operand = state.allocValue();
|
||||
eval_node(n->operand, *operand, env);
|
||||
force(operand);
|
||||
|
|
@ -332,8 +318,7 @@ struct Evaluator::Impl {
|
|||
default:
|
||||
state.error<EvalError>("unknown unary operator").debugThrow();
|
||||
}
|
||||
}
|
||||
else if (auto* n = node->get_if<IfNode>()) {
|
||||
} else if (auto* n = node->get_if<IfNode>()) {
|
||||
Value* cond = state.allocValue();
|
||||
eval_node(n->cond, *cond, env);
|
||||
force(cond);
|
||||
|
|
@ -347,16 +332,14 @@ struct Evaluator::Impl {
|
|||
} else {
|
||||
eval_node(n->else_branch, v, env);
|
||||
}
|
||||
}
|
||||
else if (auto* n = node->get_if<LetNode>()) {
|
||||
} else if (auto* n = node->get_if<LetNode>()) {
|
||||
auto let_env = make_env(env);
|
||||
for (const auto& [name, expr] : n->bindings) {
|
||||
Value* val = make_thunk(expr, env);
|
||||
let_env->bind(val);
|
||||
}
|
||||
eval_node(n->body, v, let_env);
|
||||
}
|
||||
else if (auto* n = node->get_if<LetRecNode>()) {
|
||||
} else if (auto* n = node->get_if<LetRecNode>()) {
|
||||
auto letrec_env = make_env(env);
|
||||
std::vector<Value*> thunk_vals;
|
||||
|
||||
|
|
@ -367,8 +350,7 @@ struct Evaluator::Impl {
|
|||
}
|
||||
|
||||
eval_node(n->body, v, letrec_env);
|
||||
}
|
||||
else if (auto* n = node->get_if<AttrsetNode>()) {
|
||||
} else if (auto* n = node->get_if<AttrsetNode>()) {
|
||||
auto bindings = state.buildBindings(n->attrs.size());
|
||||
|
||||
IREnvironment* attr_env = env;
|
||||
|
|
@ -391,8 +373,7 @@ struct Evaluator::Impl {
|
|||
}
|
||||
|
||||
v.mkAttrs(bindings.finish());
|
||||
}
|
||||
else if (auto* n = node->get_if<SelectNode>()) {
|
||||
} else if (auto* n = node->get_if<SelectNode>()) {
|
||||
Value* obj = state.allocValue();
|
||||
eval_node(n->expr, *obj, env);
|
||||
force(obj);
|
||||
|
|
@ -421,8 +402,7 @@ struct Evaluator::Impl {
|
|||
} else {
|
||||
state.error<EvalError>("attribute not found").debugThrow();
|
||||
}
|
||||
}
|
||||
else if (auto* n = node->get_if<HasAttrNode>()) {
|
||||
} else if (auto* n = node->get_if<HasAttrNode>()) {
|
||||
Value* obj = state.allocValue();
|
||||
eval_node(n->expr, *obj, env);
|
||||
force(obj);
|
||||
|
|
@ -440,8 +420,7 @@ struct Evaluator::Impl {
|
|||
auto attr = obj->attrs()->get(sym);
|
||||
v.mkBool(attr != nullptr);
|
||||
}
|
||||
}
|
||||
else if (auto* n = node->get_if<WithNode>()) {
|
||||
} else if (auto* n = node->get_if<WithNode>()) {
|
||||
Value* attrs = state.allocValue();
|
||||
eval_node(n->attrs, *attrs, env);
|
||||
force(attrs);
|
||||
|
|
@ -453,8 +432,7 @@ struct Evaluator::Impl {
|
|||
auto with_env = make_env(env);
|
||||
with_env->with_attrs = attrs;
|
||||
eval_node(n->body, v, with_env);
|
||||
}
|
||||
else if (auto* n = node->get_if<AssertNode>()) {
|
||||
} else if (auto* n = node->get_if<AssertNode>()) {
|
||||
Value* cond = state.allocValue();
|
||||
eval_node(n->cond, *cond, env);
|
||||
force(cond);
|
||||
|
|
@ -468,8 +446,7 @@ struct Evaluator::Impl {
|
|||
}
|
||||
|
||||
eval_node(n->body, v, env);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
v.mkNull();
|
||||
}
|
||||
}
|
||||
|
|
@ -478,10 +455,9 @@ struct Evaluator::Impl {
|
|||
Evaluator::Evaluator(EvalState& state) : pImpl(std::make_unique<Impl>(state)) {}
|
||||
Evaluator::~Evaluator() = default;
|
||||
|
||||
void Evaluator::eval_to_nix(const std::shared_ptr<Node>& ir_node,
|
||||
Value& result,
|
||||
void Evaluator::eval_to_nix(const std::shared_ptr<Node>& ir_node, Value& result,
|
||||
IREnvironment* env) {
|
||||
pImpl->eval_node(ir_node, result, env);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace nix_irc
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue