arora-engine 0.1.0

The Arora engine: loads and executes Arora modules (wasm and native hosts).
# Arora Engine

Welcome to the core of the project!

## WASM Executor

The Arora engine runs WASM modules — advertised with
[a custom module description format (or schema)](https://github.com/semio-ai/arora-types) —
through pluggable [`Executor`](src/executor/mod.rs) implementations.
Two are shipped today:

- [`wasm::WebAssemblyExecutor`]src/executor/wasm/mod.rs hosts modules
  via [`wasmtime`]https://docs.wasmtime.dev/ on native targets.
  Gated behind the default `wasmtime-host` feature.
- [`browser::BrowserExecutor`]src/executor/browser/mod.rs hosts modules
  via the browser's native `WebAssembly` runtime when `arora` itself is
  compiled to `wasm32-unknown-unknown`. The JS-facing wrapper lives in
  [`arora-web`]https://github.com/semio-ai/arora-sdk.

Both expose the same ABI to guests (`arora_buffer_alloc`/`free`,
`arora_function_<uuid>` exports, `arora_dispatch` / `arora_dispatch_indirect`
imports), so a module compiled once runs in either host.

## Native Executor

A [`native::NativeExecutor`](src/executor/native.rs) is available and is
capable of loading native dynamic libraries, and call the functions
declared in the module description. Beware of figuring out the right
dynamic library extension for the host platform. Gated behind the
default `native-host` feature; disabled on `wasm32-*` targets.

## Calling Module Functions

Once modules are loaded — either via [`Engine::load_module`](src/engine.rs)
directly, or via the [`load::load_module_from_parts`](src/load.rs)
convenience that takes a parsed `Header` plus the executable bytes and
also returns the module's function IDs —
their functions can be called using engine's
implementation of the [`CallBridge` trait](src/call.rs).
`arora_call` takes a `Call` description holding generic `Value`s as an input,
and returns a `CallResult` holding the return value
and the mutated parameters.
The engine also advertises a function called `arora_dispatch`
in the module's runtime context, so that they can call one another.
It is recommended to use the bindings generated by
[`arora-module-cli`](../arora-module-authoring/cli/readme.md),
rather than calling these functions directly.

The host of the engine (the process loading this library)
can also register native functions using [`arora_register_callable`](src/call.rs).
An `u64` identifier is attributed to each registered function,
so that they can be called later using `arora_call_indirect` from the host side,
or from any module via `arora_dispatch_indirect`.

> [Behavior Trees]https://github.com/semio-ai/arora-behavior-tree typically use this mechanism
> to wrap the various node functions into uniform tick functions.

### Call Mechanism

When a call is performed, its description is serialized into a raw buffer,
using the [Arora Buffers library](../arora-buffers/readme.md),
copied into the module's memory
(allocated using `arora_buffer_alloc` that must be exported by the modules),
before the function is called with a pointer to the memory segment.
The module is in charge of deserializing it
and serializing the result into a new buffer,
that the engine will free using `arora_buffer_free`.