Page
Maestro Extension Guide
Related docs:
Overview
Maestro runtime extensions are POSIX shared libraries in .so format.
An extension library is loaded into a maestro_ctx, then registers
host-provided external function bindings by name. This makes dynamic
libraries the canonical way to extend an existing maestrovm binary
without rebuilding the runtime itself.
Required Entry Symbol
Every extension library must export:
int maestro_dll_init(maestro_ctx *ctx);
The public symbol name is also available as
../include/maestro/common.h.
Return 0 on success. Any non-zero result is treated as an extension
load failure.
Registering Functions
Inside maestro_dll_init(), register each external function binding
with:
int maestro_register_fn(maestro_ctx *ctx, const char *name, maestro_fn fn);
Duplicate registrations are rejected.
Callback Contract
An external binding uses:
typedef int (*maestro_fn)(maestro_ctx *ctx, maestro_value **args,
size_t argc, maestro_value **result);
Ownership rules:
args[i]are borrowed for the duration of the callback- the callback must not free or mutate borrowed argument handles
*resultmust be set to a runtime-owned value created forctx- the runtime frees that returned value after it has cloned or consumed it
Minimal Example
#include "maestro/maestro.h"
static int fn_host_int(maestro_ctx *ctx, maestro_value **args, size_t argc,
maestro_value **result) {
(void)args;
if (!ctx || !result || argc != 0)
return MAESTRO_ERR_RUNTIME;
*result = maestro_value_new_int(ctx, 7);
return *result ? 0 : MAESTRO_ERR_NOMEM;
}
int maestro_dll_init(maestro_ctx *ctx) {
return maestro_register_fn(ctx, "host-int", fn_host_int);
}
Building an Extension
Build a shared library with position-independent code:
cc -Iinclude -Wall -Wextra -Werror -std=c11 -O2 -fPIC -shared \
-o plugin.so plugin.c
The runtime process must export Maestro API symbols globally. The
repository build does this for ../build/maestrovm
and the DLL integration test binary.
Loading Extensions
From the runtime API:
int maestro_ctx_load_dll(maestro_ctx *ctx, const char *path);
From the CLI:
build/maestrovm -l plugin.so -d app -r "app main" ""
Common Failures
- missing
maestro_dll_initexport - non-zero return from
maestro_dll_init - duplicate calls to
maestro_register_fn()for the same function name - loading an artifact whose required external names are not registered