feat(tvix/eval): insert import into the builtins itself
Adding `import` to builtins causes causes a bootstrap cycle because the `import` builtin needs to be initialised with the set of globals before being inserted into the globals, which also must contain itself. To break out of the cycle this hack wraps the builtins passed to the compiler in an `Rc` (probably sensible anyways, as they will end up getting cloned a bunch), containing a RefCell which gives us mutable access to the builtins. This opens up a potentially dangerous footgun in which we could mutate the builtins at runtime leading to different compiler invocations seeing different builtins, so it'd be nice to have some kind of "finalised" status for them or some such, but I'm not sure how to represent that atm. Change-Id: I25f8d4d2a7e8472d401c8ba2f4bbf9d86ab2abcb Reviewed-on: https://cl.tvl.fyi/c/depot/+/6867 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
This commit is contained in:
parent
880ea8a8fe
commit
4b9178fa2a
4 changed files with 32 additions and 14 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{cell::RefCell, path::PathBuf, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
builtins::global_builtins,
|
||||
|
|
@ -59,13 +59,21 @@ pub fn interpret(code: &str, location: Option<PathBuf>, options: Options) -> Eva
|
|||
}
|
||||
|
||||
// TODO: encapsulate this import weirdness in builtins
|
||||
let mut builtins = global_builtins();
|
||||
|
||||
let builtins = Rc::new(RefCell::new(global_builtins()));
|
||||
|
||||
#[cfg(feature = "impure")]
|
||||
builtins.insert(
|
||||
"import",
|
||||
Value::Builtin(crate::builtins::impure::builtins_import(source.clone())),
|
||||
);
|
||||
{
|
||||
// We need to insert import into the builtins, but the
|
||||
// builtins passed to import must have import *in it*.
|
||||
let import = Value::Builtin(crate::builtins::impure::builtins_import(
|
||||
builtins.clone(),
|
||||
source.clone(),
|
||||
));
|
||||
|
||||
builtins.borrow_mut().insert("import", import);
|
||||
// TODO: also add it into the inner builtins set
|
||||
};
|
||||
|
||||
let result = if options.dump_bytecode {
|
||||
crate::compiler::compile(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue