Struct ScriptFn

Source
pub struct ScriptFn { /* private fields */ }
Expand description

Assembly code for the Ad Astra Virtual Machine, ready for execution.

You can create this object using the compile function, and then run it using the ScriptFn::run function.

The ScriptFn object is cheap to Clone. In the case of cloning, each clone shares the same assembly code memory, but the execution context is unique to each clone.

§Virtual Machine Design Overview

The assembly code design is currently an implementation detail and is subject to continuous improvements, optimizations, and changes in future minor versions of Ad Astra. For this reason, the crate API does not provide direct access to manually alter the assembly code. However, for debugging purposes, you can print the internals to the terminal using the Debug implementation of the ScriptFn object.

The ScriptFn consists of Ad Astra assembly commands for the main script module function (the top-level source code of a module itself serves as the body of a function with zero parameters), as well as the assembly commands for other script functions from this module.

The runtime executes each assembly command of the script function sequentially. Some commands can conditionally or unconditionally jump to other commands in the list.

The commands interact with the stack of the current thread by pulling some Cells from the stack and pushing new Cells onto the stack. Therefore, the Virtual Machine is a stack-based machine.

§Isolation

Each assembly command is evaluated in a virtual environment. If for any reason a command fails, the Virtual Machine immediately stops execution and returns a RuntimeError from the ScriptFn::run function.

You can manually interrupt script function execution using the hook mechanism. By setting a hook function with the set_runtime_hook function, you enforce the Virtual Machine to report every command execution to the hook. The hook, in turn, can return false to signal the Virtual Machine to stop execution and return from ScriptFn::run with a RuntimeError::Interrupted error.

use ad_astra::interpret::set_runtime_hook;

set_runtime_hook(|_origin| true);

The hook function is configured per OS process thread. By default, the thread from which you call the ScriptFn::run function does not have a configured hook, meaning that you trust the script to finish its job without interruptions. In this trusting mode, script functions are executed slightly faster than with a configured hook, but the downside is that you cannot revoke control flow back to Rust until the Virtual Machine finishes its job. This could be an issue, for example, if the script code contains unconditional infinite loops.

Additionally, the hook function receives an Origin object as an argument that roughly points to the original source code statements and expressions of the script module that are about to be evaluated. You can use this feature to organize interactive script evaluation.

§Source Maps

In addition to the assembly commands, the ScriptFn object also holds a mapping between the assembly commands and the source ranges from which these commands were compiled.

The Virtual Machine uses this metadata to provide proper and descriptive runtime errors if a script execution flow ends with a script evaluation error.

§Concurrent Evaluation

Each script function is executed on the current OS thread from which it was run.

The Ad Astra base language does not provide a built-in mechanism for asynchronous script evaluation or thread management. However, you can organize a multi-threaded execution environment depending on your design goals using the export system.

For example, you can export a function from Rust to a script that takes another function as a parameter (e.g., Fn0). In the script, the author can call this exported Rust function, passing a script-defined function as an argument. The Rust function can then execute the provided script function in another thread.

#[export]
pub fn foo(f: Fn0<()>) {
    spawn(move || {
        let f = f;

        let _ = f();
    });
}

Implementations§

Source§

impl ScriptFn

Source

pub fn run(&self) -> RuntimeResult<Cell>

Evaluates the script.

The function returns the evaluation result in the form of a Cell, representing an object returned by the script using the return 100; statement. If the script does not return any value, the function returns Cell::nil.

If the script encounters a runtime error during execution, the function halts script execution immediately and returns a RuntimeError.

If the script execution is interrupted by the execution hook (configured via set_runtime_hook), this function returns a RuntimeError::Interrupted error.

By default, the current OS thread does not have a script hook, meaning that the Virtual Machine will execute the script until the end of the script’s control flow.

Source

pub fn set_context(&mut self, context: Cell)

Sets the value of the self script variable, allowing the module’s source code to read script input data.

You can create the Cell using the Cell::give constructor by passing a value of any type known to the Ad Astra Runtime (either any built-in Rust type or any type exported using the export macro).

Each clone of the ScriptFn object may have a unique context value, but the context can only be set once per ScriptFn instance. Subsequent calls to the set_context function will not change the previously set context.

By default, the ScriptFn instance does not have an evaluation context, and the self variable is interpreted as “nil” within the script code.

Note that the script’s self variable is generally mutable if the type of the value supports mutations (e.g., number types are mutable). Thus, the self script variable can serve as both a data input and output channel. If the value you set as the context is intended as the script’s output, consider reading this value after the script evaluation using the get_context function.

Source

pub fn get_context(&self) -> &Cell

Provides access to the value of the script’s self variable, as previously set by the set_context function.

By default, if the ScriptFn instance does not have an evaluation context value, this function returns Cell::nil.

Trait Implementations§

Source§

impl Clone for ScriptFn

Source§

fn clone(&self) -> ScriptFn

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ScriptFn

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ScriptFn

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'a> Downcast<'a> for ScriptFn

Source§

fn downcast(origin: Origin, provider: Provider<'a>) -> RuntimeResult<Self>

Transforms Script data into Rust data. Read more
Source§

fn hint() -> TypeHint

Returns a rough estimation of the Script type (or a set of types) from which the target Rust type could be inferred. Read more
Source§

impl ScriptBinding for ScriptFn

Source§

type RHS = DynamicType

A rough estimation of the type of the right-hand side of the operation. Read more
Source§

fn script_binding(_origin: Origin, lhs: Arg, rhs: Arg) -> RuntimeResult<()>

Operation implementation. Read more
Source§

impl ScriptInvocation for ScriptFn

Source§

fn invoke( origin: Origin, lhs: Arg, arguments: &mut [Arg], ) -> RuntimeResult<Cell>

Operation implementation. Read more
Source§

fn hint() -> Option<&'static InvocationMeta>

Returns the invocation signature description. Read more
Source§

impl<'a> Upcast<'a> for ScriptFn

Source§

type Output = Box<ScriptFn>

A type into which the input type will be upcasted. Read more
Source§

fn upcast(_origin: Origin, this: Self) -> RuntimeResult<Self::Output>

Creates Script data from Rust data. Read more
Source§

fn hint() -> TypeHint

Returns a rough estimation of the Script type (or a set of types) into which the source Rust type could be upcasted. Read more
Source§

impl ScriptClone for ScriptFn

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ScriptType for T
where T: RegisteredType + ?Sized,

Source§

fn type_meta() -> &'static TypeMeta

Returns the introspection metadata of this Rust type registered in the Script Engine.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.