Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Lazy attribute names #4154

Draft
wants to merge 29 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5ddfd1a
Move attribute selection code to Values
infinisil Oct 15, 2020
e8fbaf6
Introduce Expr::evalAttr
infinisil Oct 19, 2020
48511ea
Unroll first iteration of ExprSelect loop to avoid thunk allocation
infinisil Oct 21, 2020
35d5be4
Introduce ExprLazyBinOp and tLazyBinOp
infinisil Oct 19, 2020
5b1ef7b
Make ExprOpUpdate be an ExprLazyBinOp
infinisil Oct 19, 2020
152048d
Allocate LazyBinOp values separately from Value
infinisil Oct 21, 2020
f7c3553
Evaluate ExprOpUpdate sides with maybeThunk
infinisil Oct 21, 2020
7b947a7
Pass left/right lazyBinOp to update functions directly
infinisil Oct 23, 2020
4a2c47a
Implement noAllocationValue for Expr's and use it to avoid some allocs
infinisil Oct 24, 2020
e8a7a5b
Disable all inf rec checking for now
infinisil Oct 27, 2020
f99249d
Implement infinite recursion detection again
infinisil Dec 1, 2020
0edad24
Simplify lazyBinOp handling a bit
infinisil Dec 2, 2020
d1d9f1e
Use bitfields for LazyBinOp blackholes
infinisil Dec 2, 2020
d89a995
Remove duplicated methods by implementing evaluation handlers
infinisil Dec 4, 2020
1642440
Split fromValue into handleAttrs and handleLazyBinOp
infinisil Dec 4, 2020
272c728
Better EvalHandler design
infinisil Dec 4, 2020
b86bd8a
Simplify eval handler calling and rename to EvalStrategy
infinisil Dec 4, 2020
3584b83
Reimplement ExprSelect loop unroll
infinisil Dec 4, 2020
ca1201f
Small lazyBinOp optimizations
infinisil Dec 4, 2020
42a8ff1
Fix __curPos test
infinisil Dec 5, 2020
e291fc6
More position info
infinisil Dec 5, 2020
b97295e
Rename tLazyBinOp to tLazyUpdate
infinisil Dec 5, 2020
a5add93
Remove Env and ExprLazy from LazyBinOp
infinisil Dec 5, 2020
acecc9d
Embed LazyBinOp values into Value
infinisil Dec 5, 2020
e5a3b04
bitfield union magic
infinisil Dec 5, 2020
5af84e6
Change strategy function returns to void, blackhole optimizations
infinisil Dec 5, 2020
ba195b7
builtins.lazyAttrUpdate and make // strict by default
infinisil Dec 5, 2020
cff6f8f
Revert "Implement noAllocationValue for Expr's and use it to avoid so…
infinisil Dec 5, 2020
c3bbb4d
Remove Expr::getPos again
infinisil Dec 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions src/libexpr/eval-inline.hh
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,52 @@ LocalNoInlineNoReturn(void throwTypeError(const Pos & pos, const char * s, const
});
}


void EvalState::forceValue(Value & v, const Pos & pos)
void EvalState::evalValueWithStrategy(Value & v, EvalStrategy & strat, const Pos & pos)
{
if (v.type == tThunk) {
Env * env = v.thunk.env;
Expr * expr = v.thunk.expr;
try {
// tBlackhole indicates that any further forcing of this value should throw inf rec
// However, this only causes inf rec when the forcing happens *before* the value is assigned its final value
// Meaning that within the expr->eval you'd have to do `<evaluations>; v.type = <result>`
// However, if expressions implement their own infinite recursion check (like ExprOpUpdate!), it can do
// `v.type = <something>; <evaluations>`
// Which means that the infinite recursion detection from this forceValue is prevented, since the tBlackhole is unset before the potentially recursive evaluations
v.type = tBlackhole;
//checkInterrupt();
expr->eval(*this, *env, v);
expr->evalWithStrategy(*this, *env, v, strat);
} catch (...) {
v.type = tThunk;
v.thunk.env = env;
v.thunk.expr = expr;
throw;
}
}
else if (v.type == tAttrs)
strat.handleAttrs(*this, v);
else if (v.type == tLazyUpdate || v.type == tLazyUpdateLeftBlackhole)
// TODO: positions are not as precise as they could be
reevalLazyUpdateWithStrategy(v, strat, pos, pos);
else if (v.type == tApp)
callFunction(*v.app.left, *v.app.right, v, noPos);
callFunctionWithStrategy(*v.app.left, *v.app.right, v, strat, pos);
else if (v.type == tBlackhole)
throwEvalError(pos, "infinite recursion encountered");
throwEvalError(pos, "infinite recursion encountered (tBlackhole in forceValue)");
}

void EvalState::forceValue(Value & v, const Pos & pos)
{
evalValueWithStrategy(v, ForceEvalStrategy::getInstance(), pos);
}

Attr * EvalState::evalValueAttr(Value & v, const Symbol & name, const Pos & pos)
{
// No need to set tBlackhole's here, because evaluating attributes of values doesn't require evaluation, and inf rec within lazyBinOps is handled by them directly

auto strat = AttrEvalStrategy(name);
evalValueWithStrategy(v, strat, pos);
return strat.getAttr();
}

inline void EvalState::forceAttrs(Value & v)
{
Expand Down
Loading