| Crates.io | polkavm-ffi |
| lib.rs | polkavm-ffi |
| version | 0.1.0 |
| created_at | 2025-12-31 06:34:23.885191+00 |
| updated_at | 2025-12-31 06:34:23.885191+00 |
| description | C FFI bindings for PolkaVM - execute PVM programs from any language |
| homepage | |
| repository | https://github.com/rotkonetworks/romio |
| max_upload_size | |
| id | 2014035 |
| size | 33,301 |
C FFI bindings for PolkaVM - execute PVM programs from any language.
This crate provides a C-compatible FFI layer for PolkaVM, enabling:
#include <stdint.h>
// Opaque handles
typedef void* PvmEngine;
typedef void* PvmModule;
typedef void* PvmInstance;
typedef struct {
uint32_t status; // 0=HALT, 1=PANIC, 2=OOG, 3=FAULT, 4=HOST, 5=STEP
int64_t gas_remaining;
uint32_t host_call;
} PvmResult;
// Load and run a PVM program
PvmEngine engine = pvm_engine_new();
PvmModule module = pvm_module_new(engine, blob_data, blob_len);
PvmInstance instance = pvm_instance_new(engine, module);
pvm_instance_set_gas(instance, 1000000);
pvm_instance_prepare_call(instance, entry_pc);
PvmResult result = pvm_instance_run(instance);
if (result.status == 0) {
// Program completed successfully
uint64_t ret = pvm_instance_get_reg(instance, 7); // A0
}
// Cleanup
pvm_instance_free(instance);
pvm_module_free(module);
pvm_engine_free(engine);
using Libdl
const libpvm = dlopen("libpolkavm_ffi.so")
# Function bindings
pvm_engine_new = dlsym(libpvm, :pvm_engine_new)
pvm_module_new = dlsym(libpvm, :pvm_module_new)
pvm_instance_new = dlsym(libpvm, :pvm_instance_new)
pvm_instance_set_gas = dlsym(libpvm, :pvm_instance_set_gas)
pvm_instance_run = dlsym(libpvm, :pvm_instance_run)
# Load and run
engine = @ccall $pvm_engine_new()::Ptr{Cvoid}
module = @ccall $pvm_module_new(engine::Ptr{Cvoid}, blob::Ptr{UInt8}, len::Csize_t)::Ptr{Cvoid}
instance = @ccall $pvm_instance_new(engine::Ptr{Cvoid}, module::Ptr{Cvoid})::Ptr{Cvoid}
@ccall $pvm_instance_set_gas(instance::Ptr{Cvoid}, 1_000_000::Int64)::Cvoid
result = @ccall $pvm_instance_run(instance::Ptr{Cvoid})::NTuple{3,UInt32}
pvm_engine_new() - Create engine with JIT backendpvm_engine_new_interpreter() - Create engine with interpreter backendpvm_engine_free(engine) - Free enginepvm_module_new(engine, blob, len) - Load module from PVM blobpvm_module_new_step(engine, blob, len) - Load with step tracing enabledpvm_module_free(module) - Free modulepvm_module_memory_info(module) - Get memory map infopvm_module_exports_count(module) - Number of exportspvm_module_export_name(module, idx, buf, len) - Get export namepvm_module_export_pc(module, idx) - Get export program counterpvm_instance_new(engine, module) - Create instancepvm_instance_free(instance) - Free instancepvm_instance_reset(instance) - Reset to initial statepvm_instance_set_gas(instance, gas) - Set gas limitpvm_instance_get_gas(instance) - Get remaining gaspvm_instance_set_reg(instance, reg, value) - Set registerpvm_instance_get_reg(instance, reg) - Get registerpvm_instance_get_pc(instance) - Get program counterpvm_instance_prepare_call(instance, pc) - Prepare entry pointpvm_instance_run(instance) - Execute until completion/interruptpvm_instance_read_memory(instance, addr, buf, len) - Read memorypvm_instance_write_memory(instance, addr, data, len) - Write memorypvm_instance_sbrk(instance, pages) - Grow heappvm_instance_heap_size(instance) - Get heap size| Index | Register | Purpose |
|---|---|---|
| 0 | RA | Return address |
| 1 | SP | Stack pointer |
| 2-4 | T0-T2 | Temporaries |
| 5-6 | S0-S1 | Saved registers |
| 7-12 | A0-A5 | Arguments/return |
| Code | Status | Description |
|---|---|---|
| 0 | HALT | Normal completion |
| 1 | PANIC | Trap/panic instruction |
| 2 | OOG | Out of gas |
| 3 | FAULT | Memory access violation |
| 4 | HOST | Host call (ecalli) |
| 5 | STEP | Step trace (debug mode) |
doom - Enables Doom-specific framebuffer conversion helperscargo build --release
# Output: target/release/libpolkavm_ffi.so (or .dylib on macOS)
MIT OR Apache-2.0