pub struct Vm { /* private fields */ }
Expand description
A stack which references variables indirectly from a slab.
Implementations§
Source§impl Vm
impl Vm
Sourcepub const fn new(context: Arc<RuntimeContext>, unit: Arc<Unit>) -> Self
pub const fn new(context: Arc<RuntimeContext>, unit: Arc<Unit>) -> Self
Construct a new virtual machine.
Constructing a virtual machine is a cheap constant-time operation.
See unit_mut
and context_mut
documentation for information on
how to re-use existing Vm
’s.
Sourcepub const fn with_stack(
context: Arc<RuntimeContext>,
unit: Arc<Unit>,
stack: Stack,
) -> Self
pub const fn with_stack( context: Arc<RuntimeContext>, unit: Arc<Unit>, stack: Stack, ) -> Self
Construct a new virtual machine with a custom stack.
Sourcepub fn without_runtime(unit: Arc<Unit>) -> Self
pub fn without_runtime(unit: Arc<Unit>) -> Self
Construct a vm with a default empty RuntimeContext. This is useful when the Unit was constructed with an empty Context.
Sourcepub fn is_same(&self, context: &Arc<RuntimeContext>, unit: &Arc<Unit>) -> bool
pub fn is_same(&self, context: &Arc<RuntimeContext>, unit: &Arc<Unit>) -> bool
Test if the virtual machine is the same context and unit as specified.
Sourcepub fn is_same_context(&self, context: &Arc<RuntimeContext>) -> bool
pub fn is_same_context(&self, context: &Arc<RuntimeContext>) -> bool
Test if the virtual machine is the same context.
Sourcepub fn is_same_unit(&self, unit: &Arc<Unit>) -> bool
pub fn is_same_unit(&self, unit: &Arc<Unit>) -> bool
Test if the virtual machine is the same context.
Sourcepub fn call_frames(&self) -> &[CallFrame]
pub fn call_frames(&self) -> &[CallFrame]
Get the stack.
Sourcepub fn context_mut(&mut self) -> &mut Arc<RuntimeContext>
pub fn context_mut(&mut self) -> &mut Arc<RuntimeContext>
Access the context related to the virtual machine mutably.
Note that this can be used to swap out the RuntimeContext
associated
with the running vm. Note that this is only necessary if the underlying
Context
is different or has been modified. In contrast to
constructing a new
vm, this allows for amortised re-use of any
allocations.
After doing this, it’s important to call clear
to clean up any
residual state.
Sourcepub fn context(&self) -> &Arc<RuntimeContext>
pub fn context(&self) -> &Arc<RuntimeContext>
Access the context related to the virtual machine.
Sourcepub fn unit_mut(&mut self) -> &mut Arc<Unit>
pub fn unit_mut(&mut self) -> &mut Arc<Unit>
Access the underlying unit of the virtual machine mutably.
Note that this can be used to swap out the Unit
of execution in the
running vm. In contrast to constructing a new
vm, this allows for
amortised re-use of any allocations.
After doing this, it’s important to call clear
to clean up any
residual state.
Sourcepub fn lookup_function<N>(&self, name: N) -> Result<Function, VmError>where
N: ToTypeHash,
pub fn lookup_function<N>(&self, name: N) -> Result<Function, VmError>where
N: ToTypeHash,
Look up a function in the virtual machine by its name.
§Examples
use rune::{Context, Unit, Vm};
use std::sync::Arc;
let mut sources = rune::sources! {
entry => {
pub fn max(a, b) {
if a > b {
a
} else {
b
}
}
}
};
let context = Context::with_default_modules()?;
let runtime = Arc::new(context.runtime()?);
let unit = rune::prepare(&mut sources).build()?;
let unit = Arc::new(unit);
let vm = Vm::new(runtime, unit);
// Looking up an item from the source.
let dynamic_max = vm.lookup_function(["max"])?;
let value = dynamic_max.call::<i64>((10, 20)).into_result()?;
assert_eq!(value, 20);
// Building an item buffer to lookup an `::std` item.
let item = rune::item!(::std::i64::max);
let max = vm.lookup_function(item)?;
let value = max.call::<i64>((10, 20)).into_result()?;
assert_eq!(value, 20);
Sourcepub fn complete(self) -> Result<Value, VmError>
pub fn complete(self) -> Result<Value, VmError>
Run the given vm to completion.
If any async instructions are encountered, this will error.
Sourcepub async fn async_complete(self) -> Result<Value, VmError>
pub async fn async_complete(self) -> Result<Value, VmError>
Run the given vm to completion with support for async functions.
Sourcepub fn execute(
&mut self,
name: impl ToTypeHash,
args: impl Args,
) -> Result<VmExecution<&mut Self>, VmError>
pub fn execute( &mut self, name: impl ToTypeHash, args: impl Args, ) -> Result<VmExecution<&mut Self>, VmError>
Call the function identified by the given name.
Computing the function hash from the name can be a bit costly, so it’s worth noting that it can be precalculated:
use rune::Hash;
let name = Hash::type_hash(["main"]);
§Examples
use rune::{Context, Unit};
use std::sync::Arc;
let unit = Arc::new(Unit::default());
let mut vm = rune::Vm::without_runtime(unit);
let output = vm.execute(["main"], (33i64,))?.complete().into_result()?;
let output: i64 = rune::from_value(output)?;
println!("output: {}", output);
You can use a Vec<Value>
to provide a variadic collection of
arguments.
use rune::{Context, Unit};
use std::sync::Arc;
// Normally the unit would be created by compiling some source,
// and since this one is empty it won't do anything.
let unit = Arc::new(Unit::default());
let mut vm = rune::Vm::without_runtime(unit);
let mut args = Vec::new();
args.push(rune::to_value(1u32)?);
args.push(rune::to_value(String::from("Hello World"))?);
let output = vm.execute(["main"], args)?.complete().into_result()?;
let output: i64 = rune::from_value(output)?;
println!("output: {}", output);
Sourcepub fn send_execute(
self,
name: impl ToTypeHash,
args: impl Args + Send,
) -> Result<VmSendExecution, VmError>
pub fn send_execute( self, name: impl ToTypeHash, args: impl Args + Send, ) -> Result<VmSendExecution, VmError>
An execute
variant that returns an execution which implements
Send
, allowing it to be sent and executed on a different thread.
This is accomplished by preventing values escaping from being
non-exclusively sent with the execution or escaping the execution. We
only support encoding arguments which themselves are Send
.
Sourcepub fn call(
&mut self,
name: impl ToTypeHash,
args: impl GuardedArgs,
) -> Result<Value, VmError>
pub fn call( &mut self, name: impl ToTypeHash, args: impl GuardedArgs, ) -> Result<Value, VmError>
Call the given function immediately, returning the produced value.
This function permits for using references since it doesn’t defer its execution.
§Panics
If any of the arguments passed in are references, and that references is
captured somewhere in the call as Mut<T>
or Ref<T>
this call
will panic as we are trying to free the metadata relatedc to the
reference.
Sourcepub fn call_with_diagnostics(
&mut self,
name: impl ToTypeHash,
args: impl GuardedArgs,
diagnostics: Option<&mut dyn VmDiagnostics>,
) -> Result<Value, VmError>
pub fn call_with_diagnostics( &mut self, name: impl ToTypeHash, args: impl GuardedArgs, diagnostics: Option<&mut dyn VmDiagnostics>, ) -> Result<Value, VmError>
Call the given function immediately, returning the produced value.
This function permits for using references since it doesn’t defer its execution.
§Panics
If any of the arguments passed in are references, and that references is
captured somewhere in the call as Mut<T>
or Ref<T>
this call
will panic as we are trying to free the metadata relatedc to the
reference.
Sourcepub async fn async_call<A, N>(
&mut self,
name: N,
args: A,
) -> Result<Value, VmError>where
N: ToTypeHash,
A: GuardedArgs,
pub async fn async_call<A, N>(
&mut self,
name: N,
args: A,
) -> Result<Value, VmError>where
N: ToTypeHash,
A: GuardedArgs,
Call the given function immediately asynchronously, returning the produced value.
This function permits for using references since it doesn’t defer its execution.
§Panics
If any of the arguments passed in are references, and that references is
captured somewhere in the call as Mut<T>
or Ref<T>
this call will panic as we are trying to free the metadata relatedc to
the reference.
Sourcepub fn with<F, T>(&self, f: F) -> Twhere
F: FnOnce() -> T,
pub fn with<F, T>(&self, f: F) -> Twhere
F: FnOnce() -> T,
Call the provided closure within the context of this virtual machine.
This allows for calling protocol function helpers like Value::display_fmt which requires access to a virtual machine.
use rune::{Value, Vm};
use rune::runtime::{Formatter, VmError};
fn use_with(vm: &Vm, output: &Value, f: &mut Formatter) -> Result<(), VmError> {
vm.with(|| output.display_fmt(f)).into_result()?;
Ok(())
}