Struct lualite::runtime::VirtualMachine
source · [−]pub struct VirtualMachine { /* private fields */ }
Expand description
Bytecode evaluation engine
Attach compiled functions to a VirtualMachine
with insert_function
or initialize it
with a list of functions using with_functions
.
Begin execution with run
.
Implementations
sourceimpl VirtualMachine
impl VirtualMachine
pub fn new() -> Self
sourcepub fn with_functions<I, S, P>(functions: I) -> Self where
I: IntoIterator<Item = (S, P)>,
S: Into<String>,
P: Into<Procedure>,
pub fn with_functions<I, S, P>(functions: I) -> Self where
I: IntoIterator<Item = (S, P)>,
S: Into<String>,
P: Into<Procedure>,
Construct a VirtualMachine
with an iterator of functions.
pub fn insert_function<S: Into<String>, P: Into<Procedure>>(
&mut self,
name: S,
procedure: P
)
pub fn remove_function<S: AsRef<str>>(
&mut self,
name: S
) -> Option<Rc<Procedure>>
pub fn get_function<S: AsRef<str>>(&self, name: S) -> Option<Rc<Procedure>>
sourceimpl VirtualMachine
impl VirtualMachine
sourcepub fn run(
&mut self,
entry_name: &str,
args: impl IntoIterator<Item = Value>
) -> Result<Value, RuntimeError>
pub fn run(
&mut self,
entry_name: &str,
args: impl IntoIterator<Item = Value>
) -> Result<Value, RuntimeError>
Run the virtual machine to completion, starting with the function referred to
by entry_name
. If it does not exist in the virtual machine, a RuntimeError
is returned. Otherwise, is used to lookup the entry function by name.
The entry function is called with the values in args
and its return value is
returned by this function as a Value
.
Infinite loops:
Using run
will continue to execute bytecode until entry_name
finishes and
returns. This could potentially cause an unrecoverable infinite loop. Use
initialize_with_values
and
execution_loop
for more fine-grained control over
the number of instructions to allow the VM to execute.
Example:
let source_code = r"
function trisum(a, b, c)
return a + b + c
end
";
let (_, declarations) = parser::parse_file(source_code).unwrap();
let functions = compiler::compile_declarations(declarations.iter());
let mut vm = VirtualMachine::with_functions(functions);
let result = vm.run("trisum", [1.into(), 2.into(), 3.into()]);
assert!(matches!(result, Ok(Value::Integer(6))));
sourcepub fn get_result(&self) -> Value
pub fn get_result(&self) -> Value
Gets the return value of the entry function.
This will always be Value::Nil
if the entry function has not finished.
sourcepub fn initialize_with_values(
&mut self,
entry_procedure: Rc<Procedure>,
args: impl IntoIterator<Item = Value>
) -> Result<(), RuntimeError>
pub fn initialize_with_values(
&mut self,
entry_procedure: Rc<Procedure>,
args: impl IntoIterator<Item = Value>
) -> Result<(), RuntimeError>
sourcepub fn execution_loop(
&mut self,
limit: InstructionCount
) -> Result<ExecutionStatus, RuntimeError>
pub fn execution_loop(
&mut self,
limit: InstructionCount
) -> Result<ExecutionStatus, RuntimeError>
Execute instructions until either limit
is reached or the entry procedure finishes.
Example:
let source_code = r"
function forever(n) # causes an infinite loop when n >= 0
x = 0
while x >= 0 do
x = x + n
end
end
";
let (_, fn_decl) = parser::declaration::function_decl(source_code).expect("parse failed");
let procedure = compiler::compile_function(&fn_decl);
let mut vm = VirtualMachine::new();
// Initialize a call to: forever(10)
vm.initialize_with_values(Rc::new(procedure), [Value::Integer(10)]);
// Run for 200 instructions
let status = vm.execution_loop(InstructionCount::Limited(200));
assert!(matches!(status, Ok(ExecutionStatus::Unfinished))); // Did not finish
// Continue to run for 5000 more instructions
let status = vm.execution_loop(InstructionCount::Limited(5000));
assert!(matches!(status, Ok(ExecutionStatus::Unfinished))); // Will always return Unfinished
sourceimpl VirtualMachine
impl VirtualMachine
sourcepub fn execute(&mut self, instruction: Instruction) -> Result<(), RuntimeError>
pub fn execute(&mut self, instruction: Instruction) -> Result<(), RuntimeError>
Execute a single bytecode instruction
Trait Implementations
sourceimpl Debug for VirtualMachine
impl Debug for VirtualMachine
Auto Trait Implementations
impl !RefUnwindSafe for VirtualMachine
impl !Send for VirtualMachine
impl !Sync for VirtualMachine
impl Unpin for VirtualMachine
impl !UnwindSafe for VirtualMachine
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more