Description
Hi,
I am trying to use eval_function()
to call Starlark functions from Rust, as per the doc.
However, it seems that as long as the module is loaded, the values allocated on the heap passed to eval_function are never freed? The heap keeps growing indefinitely.
I have tried adding verbose_gc()
to see if the garbage collector is run, but it shows nothing.
At first I thought it was an issue with my custom type definition, but it seems to behave the same with a standard rust type (ex: heap.alloc("qwe".to_string())
.
I tried running it through a different evaluator each time (thinking each evaluator would have its own heap, but that's not the case).
Is there a way to call a function without leaking, except reloading the AST into a new module each time?
Best regards
Unrelated question : what is freeze all about? There are references to it everywhere in the doc, but no explanation about what it entails, when one should use it, ...
use starlark::{
environment::{Globals, Module},
eval::Evaluator,
starlark_simple_value,
syntax::{AstModule, Dialect},
values::{starlark_value, Coerce, Freeze, NoSerialize, ProvidesStaticType, StarlarkValue},
};
starlark_simple_value!(T);
#[derive(
Default,
Coerce,
ProvidesStaticType,
NoSerialize,
Debug,
allocative::Allocative,
starlark::values::Trace,
Freeze,
derive_more::Display,
)]
#[repr(C)]
struct T {
a: i64,
}
#[starlark_value(type = "T")]
impl<'v> StarlarkValue<'v> for T {}
fn main() {
let script = r#"
def x(a):
pass
x
"#;
let ast = AstModule::parse("x.star", script.to_owned(), &Dialect::Extended).unwrap();
let globals = Globals::standard();
let module = Module::new();
let mut eval = Evaluator::new(&module);
eval.verbose_gc();
let _ = eval.eval_module(ast, &globals).unwrap();
loop {
let x = module.get("x").unwrap();
let heap = eval.heap();
let _ = eval
// .eval_function(x, &[heap.alloc(T::default())], &[])
//.eval_function(x, &[heap.alloc(5)], &[])
.eval_function(x, &[heap.alloc("qwe".to_string())], &[])
.unwrap();
println!("Allocated: {}", heap.allocated_bytes());
}
}