about summary refs log tree commit diff
path: root/tvix/eval/src/chunk.rs
AgeCommit message (Collapse)AuthorFilesLines
2023-01-21 r/5721 refactor(tvix/eval): administer antidote for poisonAdam Joseph1-3/+2
The codebase contains a lot of complexity and odd roundabout handling for shadowing globals. I'm pretty sure none of this is necessary, and all of it disappears if you simply make the globals part of the ordinary identifier resolution chain, with their own scope up above the root scope. Then the ordinary shadowing routines do the right thing, and no special cases or new terminology are required. This commit does that. Note by tazjin: This commit was originally abandoned when Adam decided not to take away reviewer bandwidth for this at the time (eval was still in a much earlier stage). As we've recently done some significant refactoring of globals initialisation this came up again, and it seems we can easily cover the use-cases of the poison tracking in other ways now, so I've rebased, updated and resurrected the CL. Co-Authored-By: Vincent Ambo <tazjin@tvl.su> Signed-off-by: Adam Joseph <adam@westernsemico.com> Change-Id: Ib3309a47a7b31fa5bf10466bade0d876b76ae462 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7089 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de>
2022-11-04 r/5236 fix(tvix/eval): remove impl PartialEq for ValueAdam Joseph1-1/+1
It isn't possible to implement PartialEq properly for Value, because any sensible implementation needs to force() thunks, which cannot be done without a `&mut VM`. The existing derive(PartialEq) has false negatives, which caused the bug which cl/7142 fixed. Fortunately that bug was easy to find, but a silent false negative deep within the bowels of nixpkgs could be a real nightmare to hunt down. Let's just remove the PartialEq impl for Value, and the other derive(PartialEq)'s that depend on it. Signed-off-by: Adam Joseph <adam@westernsemico.com> Change-Id: Iacd3726fefc7fc1edadcd7e9b586e04cf8466775 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7144 Reviewed-by: kanepyork <rikingcoding@gmail.com> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
2022-10-19 r/5159 feat(tvix/eval): deduplicate overlap between Closure and ThunkAdam Joseph1-1/+7
This commit deduplicates the Thunk-like functionality from Closure and unifies it with Thunk. Specifically, we now have one and only one way of breaking reference cycles in the Value-graph: Thunk. No other variant contains a RefCell. This should make it easier to reason about the behavior of the VM. InnerClosure and UpvaluesCarrier are no longer necessary. This refactoring allowed an improvement in code generation: `Rc<RefCell<>>`s are now created only for closures which do not have self-references or deferred upvalues, instead of for all closures. OpClosure has been split into two separate opcodes: - OpClosure creates non-recursive closures with no deferred upvalues. The VM will not create an `Rc<RefCell<>>` when executing this instruction. - OpThunkClosure is used for closures with self-references or deferred upvalues. The VM will create a Thunk when executing this opcode, but the Thunk will start out already in the `ThunkRepr::Evaluated` state, rather than in the `ThunkRepr::Suspeneded` state. To avoid confusion, OpThunk has been renamed OpThunkSuspended. Thanks to @sterni for suggesting that all this could be done without adding an additional variant to ThunkRepr. This does however mean that there will be mutating accesses to `ThunkRepr::Evaluated`, which was not previously the case. The field `is_finalised:bool` has been added to `Closure` to ensure that these mutating accesses are performed only on finalised Closures. Both the check and the field are present only if `#[cfg(debug_assertions)]`. Change-Id: I04131501029772f30e28da8281d864427685097f Signed-off-by: Adam Joseph <adam@westernsemico.com> Reviewed-on: https://cl.tvl.fyi/c/depot/+/7019 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
2022-10-16 r/5142 feat(tvix/eval): remove Clone instance from Chunk and LambdaAdam Joseph1-1/+1
Lambda has a quite large and variable-sized runtime representation, unlike Rc<Lambda>. It would be easy to accidentally call clone() on this and create input-dependent performance regressions. Nothing in the codebase is currently using Lambda.clone(). Let's remove the derived instance. If it's really needed it is very easy to add it back in, but whoever does that will have to look at the struct they're adding Clone to, which will hopefully prompt them to think about whether or not that's really what they want to do. Change-Id: I7806a741862ab4402229839ce3f4ea75aafd6d12 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7029 Autosubmit: Adam Joseph <adam@westernsemico.com> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
2022-10-05 r/5035 refactor(tvix/eval): introduce source::SourceCode typeVincent Ambo1-14/+4
This type hides away the lower-level handling of most codemap data structures, especially to library consumers (see corresponding changes in tvixbolt). This will help with implement `import` by giving us central control over how the codemap works. Change-Id: Ifcea36776879725871b30c518aeb96ab5fda035a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6855 Tested-by: BuildkiteCI Reviewed-by: wpcarro <wpcarro@gmail.com>
2022-09-18 r/4908 refactor(tvix/eval): Don't (ab)use PartialEq for Nix equalityGriffin Smith1-2/+2
Using rust's PartialEq trait to implement Nix equality semantics is reasonably fraught with peril, both because the actual laws are different than what nix expects, and (more importantly) because certain things actually require extra context to compare for equality (for example, thunks need to be forced). This converts the manual PartialEq impl for Value (and all its descendants) to a *derived* PartialEq impl (which requires a lot of extra PartialEq derives on miscellanious other types within the codebase), and converts the previous nix-semantics equality comparison into a new `nix_eq` method. This returns an EvalResult, even though it can't currently return an error, to allow it to fail when eg forcing thunks (which it will do soon). Since the PartialEq impls for Value and NixAttrs are now quite boring, this converts the generated proptests for those into handwritten ones that cover `nix_eq` instead Change-Id: If3da7171f88c22eda5b7a60030d8b00c3b76f672 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6650 Autosubmit: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
2022-09-18 r/4901 test(tvix/eval): Add proof-of-concept test for ChunkGriffin Smith1-0/+14
This is pretty boring at the moment, but mostly serves as a foot in the door in the direction of writing more tests Change-Id: Id88eb4ec7e53ebb2d5b5c254c8f45ff750238811 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6637 Autosubmit: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
2022-09-11 r/4812 feat(tvix/eval): add Chunk::pop_op methodVincent Ambo1-0/+22
This is used to drop an already emitted operation from a chunk again and clean up its span tracking. This is required in cases where the compiler has to backtrack. Change-Id: I8112da9427688bb2dec96a2ddd12390f6e9734c3 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6499 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-10 r/4786 fix(tvix/eval): fix doc comment syntax where applicableVincent Ambo1-0/+3
As pointed out by grfn on cl/6091 Change-Id: I28308577b7cf99dffb4a4fd3cc8783eb9ab4d0d6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6460 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-09 r/4777 refactor(tvix/eval): move `disassemble_op` to the Chunk structureVincent Ambo1-0/+31
Change-Id: Ic6710c609ed647bfa47d673aaf22c4da96c0f319 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6451 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-09 r/4775 feat(tvix/eval): implement DisassemblingObserver for compilerVincent Ambo1-8/+5
This type implements an observer that is called whenever the compiler emits a chunk (after the toplevel, thunks, or lambdas) and prints the output of the disassembler to its internal writer. This replaces half of the uses of the `disassembler` feature, which has been removed from the Cargo configuration. Note that at this commit runtime tracing is not yet implemented as an observer. Change-Id: I7894ca1ba445761aba4ad51d98e4a7b6445f1aea Reviewed-on: https://cl.tvl.fyi/c/depot/+/6449 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-09 r/4773 refactor(tvix/eval): index into Chunk with ConstantIdx/CodeIdxVincent Ambo1-4/+18
This is a step towards hiding the internal fields of thunk, and making the interface of the type more predictable. Part of the preparation for implementing observers. Change-Id: I1a88a96419c72eb9e2332b56a2dd94afa47e6f88 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6447 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4767 fix(tvix/eval): ensure disassembler prints continous lines correctlyVincent Ambo1-0/+9
There can be different spans on the same line, so the previous implementation would duplicate line numbers unnecessarily. Change-Id: I8d8db77177aee0d834a6ec3584641e1bd5f31c3e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6434 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4747 feat(tvix/eval): thread codemap through to disassemblerVincent Ambo1-0/+3
If the disassembler feature is enabled, make sure that an Rc of the codemap is available through the chunk. Change-Id: I700f27ab665a704f73457b19bd2d7efc93828a16 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6414 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4736 feat(tvix/eval): track source spans for builtin accessVincent Ambo1-6/+0
As of this commit, the source spans of all emitted bytecode are fully tracked. Change-Id: I4c83deee0fc3f5e6fd6acad5a39047aec693b388 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6403 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4712 feat(tvix/eval): add methods for emitting code with tracked spansVincent Ambo1-1/+8
These are not actually used yet; this is in preparation for a multi-commit chain for emitting all the right spans in the right locations. Change-Id: Ie99d6add2696c1cc0acb9ab928917a10237159de Reviewed-on: https://cl.tvl.fyi/c/depot/+/6379 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4709 feat(tvix/eval): add data structures for tracking spans in chunksVincent Ambo1-0/+50
This adds a new vector to the chunk data structure which tracks spans into a codemap. The compiler will emit this information to the chunk when adding instructions. The internal representation of the spans is slightly optimised to avoid storing duplicate spans, as there are cases where many instructions might be derived from the same span. Change-Id: I336f8c912e7eb50ea02ed71e6164f651ca3ca790 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6376 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-01 r/4576 refactor(tvix/eval): return a lambda from the compilerVincent Ambo1-1/+1
Changes the internal compiler plumbing to not just return a chunk of code, but the same chunk wrapped inside of a lambda value. This is one more step towards compiling runtime lambdas. Change-Id: If0035f8e65a2970c5ae123fc068a2396e1d8fd72 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6240 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-30 r/4534 feat(tvix/eval): implement chunk disassembler outputVincent Ambo1-1/+1
This makes for a much nicer view of an execution if `--feature disassembler` is set, for example: tvix-repl> let value = [ 1 2 { a = 1; } ]; in value ++ [ 1 ] === compiled bytecode (11 operations) === 02 OpConstant(1) 02 OpConstant(2) 02 OpConstant("a") 02 OpConstant(1) 02 OpAttrs(1) 02 OpList(3) 02 OpGetLocal(0) 02 OpConstant(1) 02 OpList(1) 02 OpConcat 02 OpCloseScope(1) === runtime trace === 0001 OpConstant(ConstantIdx(0)) [ 1 ] 0002 OpConstant(ConstantIdx(1)) [ 1 2 ] 0003 OpConstant(ConstantIdx(2)) [ 1 2 "a" ] 0004 OpConstant(ConstantIdx(3)) [ 1 2 "a" 1 ] 0005 OpAttrs(1) [ 1 2 { a = 1; } ] 0006 OpList(3) [ [ 1 2 { a = 1; } ] ] 0007 OpGetLocal(0) [ [ 1 2 { a = 1; } ] [ 1 2 { a = 1; } ] ] 0008 OpConstant(ConstantIdx(4)) [ [ 1 2 { a = 1; } ] [ 1 2 { a = 1; } ] 1 ] 0009 OpList(1) [ [ 1 2 { a = 1; } ] [ 1 2 { a = 1; } ] [ 1 ] ] 0010 OpConcat [ [ 1 2 { a = 1; } ] [ 1 2 { a = 1; } 1 ] ] 0011 OpCloseScope(1) [ [ 1 2 { a = 1; } 1 ] ] => [ 1 2 { a = 1; } 1 ] :: list Change-Id: If79c7fd1f0f18255ddb3763c1ba585fda8041b1b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6195 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-27 r/4513 refactor(tvix/eval): rename Chunk::add_* functions to ::push_*Vincent Ambo1-2/+2
grfn pointed out in cl/6069 that naming them like this makes it clear that things are being added to the end of the state. Change-Id: I6a23215c4fef713869a3c85b0dde1ebbda7637e9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6179 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-12 r/4405 feat(tvix/eval): add initial chunk representationVincent Ambo1-0/+26
Change-Id: I53202e93938bede421c8f1c98901e4c67544e257 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6069 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>