Run Bytecodes with Callback
The standard Vm::eval and Vm::eval_with_scope path is enough for ordinary scripts.
A Rhai Grain bytecodes program becomes a special case when it creates or receives a function pointer that a native Rust function later calls.
Vm::eval_with_callbacks
This is the purpose of Vm::eval_with_callbacks: it registers a native wrapper for each
transpiled function for the duration of the run, so a script that creates a closure and then
hands it to a host callback can still be resolved by Rhai.
This is necessary when the script does something like:
let values = [1, 2, 3]; // an array
values.map(|x| x * 2); // native function 'map' taking closure as callback
The Engine must be able to resolve that function pointer within the native Rust call.
Run with Callback Wrappers
use rhai::grain::{Compiler, Vm};
let engine = Engine::new();
let ast = engine.compile(script)?;
// Transpile into shared bytecodes.
let grain = Compiler::new();
let bytecodes = grain.compile(&ast).into_shared();
// Use 'eval_with_callbacks'.
let mut vm = Vm::new(&engine);
let value = vm.eval_with_callbacks(&mut scope, &bytecodes)?;
The callback-enabled path is not needed for every script.
If the script has no function pointer or closure usage,
plain Vm::eval is simpler and faster.
It becomes necessary only when Rhai must cross from native Rust back into Rhai Grain through a function pointer or a closure.