irc: PrimOp memory leak and IR_VERSION mismatch
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Iad057cd5f51ef26e7de93ccca7b3d3156a6a6964
This commit is contained in:
parent
f6481b3c01
commit
28de44c598
2 changed files with 420 additions and 69 deletions
|
|
@ -69,8 +69,6 @@ struct Evaluator::Impl {
|
|||
|
||||
explicit Impl(EvalState& s) : state(s) {}
|
||||
|
||||
// Destructor not needed - unique_ptr handles cleanup automatically
|
||||
|
||||
IREnvironment* make_env(IREnvironment* parent = nullptr) {
|
||||
auto env = new IREnvironment(parent);
|
||||
environments.push_back(std::unique_ptr<IREnvironment>(env));
|
||||
|
|
@ -99,6 +97,39 @@ struct Evaluator::Impl {
|
|||
thunks.erase(v);
|
||||
}
|
||||
|
||||
// Copy a forced value into a destination Value
|
||||
void copy_value(Value& dest, Value* src) {
|
||||
if (!src)
|
||||
return;
|
||||
force(src);
|
||||
state.forceValue(*src, noPos);
|
||||
switch (src->type()) {
|
||||
case nInt:
|
||||
dest.mkInt(src->integer());
|
||||
break;
|
||||
case nBool:
|
||||
dest.mkBool(src->boolean());
|
||||
break;
|
||||
case nString:
|
||||
dest.mkString(src->c_str());
|
||||
break;
|
||||
case nPath:
|
||||
dest.mkPath(src->path());
|
||||
break;
|
||||
case nNull:
|
||||
dest.mkNull();
|
||||
break;
|
||||
case nFloat:
|
||||
dest.mkFloat(src->fpoint());
|
||||
break;
|
||||
default:
|
||||
// For attrs, lists, functions, etc., direct assignment is safe
|
||||
// as they use reference counting internally
|
||||
dest = *src;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void eval_node(const std::shared_ptr<Node>& node, Value& v, IREnvironment* env) {
|
||||
if (!node) {
|
||||
v.mkNull();
|
||||
|
|
@ -151,36 +182,7 @@ struct Evaluator::Impl {
|
|||
if (!bound) {
|
||||
state.error<EvalError>("variable not found").debugThrow();
|
||||
}
|
||||
force(bound);
|
||||
// Copy the forced value's data into v
|
||||
// For simple types, use mk* methods to ensure proper initialization
|
||||
// For complex types (attrs, lists, functions), direct assignment is safe
|
||||
state.forceValue(*bound, noPos);
|
||||
switch (bound->type()) {
|
||||
case nInt:
|
||||
v.mkInt(bound->integer());
|
||||
break;
|
||||
case nBool:
|
||||
v.mkBool(bound->boolean());
|
||||
break;
|
||||
case nString:
|
||||
v.mkString(bound->c_str());
|
||||
break;
|
||||
case nPath:
|
||||
v.mkPath(bound->path());
|
||||
break;
|
||||
case nNull:
|
||||
v.mkNull();
|
||||
break;
|
||||
case nFloat:
|
||||
v.mkFloat(bound->fpoint());
|
||||
break;
|
||||
default:
|
||||
// For attrs, lists, functions, etc., direct assignment is safe
|
||||
// as they use reference counting internally
|
||||
v = *bound;
|
||||
break;
|
||||
}
|
||||
copy_value(v, bound);
|
||||
} else if (auto* n = node->get_if<LambdaNode>()) {
|
||||
auto lambda_env = env;
|
||||
auto body = n->body;
|
||||
|
|
@ -545,37 +547,7 @@ struct Evaluator::Impl {
|
|||
auto attr = obj->attrs()->get(sym);
|
||||
|
||||
if (attr) {
|
||||
Value* val = attr->value;
|
||||
force(val);
|
||||
// Copy the forced value's data into v
|
||||
// For simple types, use mk* methods to ensure proper initialization
|
||||
// For complex types (attrs, lists, functions), direct assignment is safe
|
||||
state.forceValue(*val, noPos);
|
||||
switch (val->type()) {
|
||||
case nInt:
|
||||
v.mkInt(val->integer());
|
||||
break;
|
||||
case nBool:
|
||||
v.mkBool(val->boolean());
|
||||
break;
|
||||
case nString:
|
||||
v.mkString(val->c_str());
|
||||
break;
|
||||
case nPath:
|
||||
v.mkPath(val->path());
|
||||
break;
|
||||
case nNull:
|
||||
v.mkNull();
|
||||
break;
|
||||
case nFloat:
|
||||
v.mkFloat(val->fpoint());
|
||||
break;
|
||||
default:
|
||||
// For attrs, lists, functions, etc., direct assignment is safe
|
||||
// as they use reference counting internally
|
||||
v = *val;
|
||||
break;
|
||||
}
|
||||
copy_value(v, attr->value);
|
||||
} else if (n->default_expr) {
|
||||
eval_node(*n->default_expr, v, env);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue