A capability-based virtual machine designed for secure, predictable, and optimized bytecode execution.
LightVM is built with a focus on execution transparency and resource efficiency:
- Zero Magic (Deterministic): Instruction execution is linear and completely predictable. The VM operates explicitly, executing instructions exactly as they are defined.
- Resource Conscious: Designed with a minimal memory footprint through the use of optimized data structures such as SmolStr and ahash for fast metadata management.
- Explicit Security: Security is managed through a strict Capability system. Every VM access and operation must have permissions explicitly defined by the host from the outset.
LightVM isn't just a simple interpreter. Before execution, your bytecode undergoes a multi-pass optimization to ensure maximum performance and minimal footprint:
- Constant Folding: Pre-calculates math and logic operations (e.g., Add, Sub, Xor, Concat) if the values are known at compile-time.
- Conversion & Metadata Folding: Pre-evaluates type casting (e.g., ToInteger, ToString) and metadata checks like TypeOf to eliminate redundant runtime work.
- Strength Reduction: Replaces "heavy" operations with lighter ones, such as converting multiplication by powers of two into bitwise Shl (Shift Left).
- Dead Store Elimination: Analyzes variable usage and automatically removes Push, Set, or Inc operations that don't contribute to the final program state.
- Dead Loop Elimination: Identifies and prunes "pure" loops that have no side effects (no I/O, calls, or returns), preventing unnecessary CPU cycles.
- Redundant Load Elimination: Detects consecutive attempts to load identical values or variables onto the stack and replaces redundant operations with a high-performance Dup instruction to minimize memory access overhead.
- Jump Optimization: Detects and removes redundant Jump instructions that point to the very next line of code.
- Jump Threading: Optimizes control flow by collapsing chains of redirection, where a jump leads directly to another jump, ensuring the instruction pointer bypasses intermediate hops to reach the final destination immediately.
Installation with NPM
npm install lightvm
# or
npm install lightvm@nextInstallation with Yarn
yarn add lightvm
# or
yarn add lightvm@nextInstallation with Cargo
cargo add lightvmUsing TypeScript:
import { LightVM, Capability } from 'lightvm';
const caps = [Capability.Control, Capability.Observe];
const vm = new LightVM(caps);Using Rust:
use lightvm::LightVM;
use lightvm::types::capability::Capability;
fn main() {
let caps = vec![Capability::Control, Capability::Observe];
let mut vm = LightVM::new(caps);
}LightVM uses a strict capability-based security model. You must explicitly grant permissions when instantiating the VM.
| Capability | Level | Description |
|---|---|---|
| Control | Low | Grants permission to start/stop execution and export functions. |
| Observe | Medium | Allows the host to inspect internal states, variable stacks, and metrics. |
| Debug | High | Opens access to verbose internal logs and hidden states for troubleshooting. |
| Unsafe | Critical | Removes safety guards, allowing manual halts and raw memory/process access. |
-
run()method:
Permission to start bytecode execution.TypeScript:
const raw = [ ["push", 5], ["val", "x"], ["set", "x"] ]; vm.load(vm.tools().optimizeBytecode(JSON.stringify(raw))) .run();
Rust:
let raw = serde_json::json!([ ["push", 5], ["val", "x"], ["set", "x"] ]); LightVM::tools().optimize_bytecode(raw) .map(|opt| vm.load(serde_json::from_str(&opt).unwrap()).run(None)) .expect("Optimization failed");
Note
Capability Required: control
Info: parameters of load() can change bytecode directly or file path to .ltc
-
provide()method:
Permission to inject data/variables into the VM.TypeScript:
vm.provide("identity", { name: "John Doe", force: "2021", });
Rust:
vm.provide("identity".to_string(), serde_json::json!({ "name": "John Doe", "force": "2021" }));
Note
Capability Required: no spesific capability
-
inspect()method:
Permission to view state, number of instructions, and capability.TypeScript:
const report = vm.inspect(); console.log(report);
Rust:
let report = vm.inspect(); println!("{}", serde_json::to_string_pretty(&report).unwrap());
Note
Capability Required: observe
-
halt()method:
Permission to force/manually stop VM.TypeScript:
vm.halt(); console.log("The VM has been terminated.")
Rust:
vm.halt(); println!("The VM has been terminated.");
Note
Capability Required: unsafe
-
export()method:
Permission to export functions in the VM out.TypeScript:
const add = vm.export("add"); console.log(add(5, 6));
Rust:
let mut add = vm.export("add".to_string()); let args = vec![serde_json::json!(5), serde_json::json!(6)]; if let Some(hasil) = add_func(args) { println!("Hasil dari VM: {}", hasil); }
Note
Capability Required: control
LightVM requires explicit type definitions for certain instructions to maintain deterministic execution and peak performance.
| Type | Aliases | Reference | Target Value Type |
|---|---|---|---|
| sht | i16 | Short | 16-bit Integer (Int16) |
| int | i32 | Integer | 32-bit Integer (Int32) |
| lng | i64 | Long | 64-bit Integer (Int64) |
| oct | i128 | Octa | 128-bit Integer (Int128) |
| hlf | f16 | Half | 16-bit Floating Point (Float16) |
| flt | f32 | Float | 32-bit Floating Point (Float32) |
| dbl | f64 | Double | 64-bit Floating Point (Float64) |
| str | - | String | String / Text data |
Warning
Preview Type: hlf (Half-precision) is currently in Preview. It's more stable than Nightly but may still undergo refinements or behavior changes.
LightVM has a total of 40+ instructions for bytecode.
- Stack & Variable Management
A group of instructions for basic data manipulation and memory (variable) allocation.
| Opcode | Arguments | Description |
|---|---|---|
| push | value | Inserting data into the stack |
| val | name | Declaring a new variable |
| set | name | Take the top stack and then save it to the variable name |
| get | name | Take the contents of the name variable and push it onto the stack |
| dup | - | Duplicate the top value in the stack |
- Arithmetic & Logic
Instructions for calculations. Note that for optimization, these instructions require aPrimitiveTypes(sht,hlf,int,flt,lng,dbl) to prevent the VM from guessing the data type during execution.
| Opcode | Arguments | Description |
|---|---|---|
| add / sub | type | Addition or Subtraction |
| mul / div | type | Multiplication or Division |
| mod | type | Modulo (Remainder) |
| inc / dec | name, type | Directly add/remove variable contents (without going through the stack) |
| gt / lt | type | Greater Than or Less Than |
| ge / le | type | Greater/Less Than or Equal |
| eq / neq | type | Equal or Not Equal |
| shl / shr | type | Shift Left or Shift Right bitwise operation based on data type |
| rol / ror | type | Circular Shift Left or Right (Rotate) bitwise operation based on data type |
| and / or | - | Boolean logic operations (&& / ||) |
| xor | - | Bitwise Exclusive OR operation between two values |
| not | - | Bitwise NOT (Inversion) operation on a single value |
Note
Specific Opcode: shl, shr, rol, and ror only accepts sht, int, and lng types from PrimitiveTypes.
- Control Flow & Function
Instructions for managing program flow, looping, and function calls.
| Opcode | Arguments | Description |
|---|---|---|
| jump | target_ip | Jump to a specific instruction line (Instruction Pointer) |
| if_false | target_ip | Jump if the value on the stack is false |
| func | name, argc, start, end, [params] | Function block definition (scope) |
| call | name, argc | Call a function with a specified number of arguments |
| return | - | Exit the function and return to the caller |
| stop | - | Kill all VM processes (Halt) |
- Data Structures & Metadata
Create complex data handles like JS Objects or Arrays, plus data type matters.
| Opcode | Arguments | Description |
|---|---|---|
| make_obj | count | Create Object from n key-value pairs in stack |
| make_array | count | Create an Array of n elements in a stack |
| access | prop_name | Access Object's properties |
| access_index | - | Access Array elements by index on the stack |
| length | - | Check the length of a string or the number of items in an array/object |
| typeof | - | Get the data type from the top value of the stack |
| concat | - | Combine two values (usually strings) |
- Type Casting (Conversion)
For those of you who want to force a certain data type to ensure consistent performance.
| Opcode | Description |
|---|---|
| to_string | Change the value to String |
| to_short | Change value to Short (16-bit) |
| to_integer | Change value to Integer (32-bit) |
| to_long | Change the value to Long (64-bit) |
| to_half | Change value to Half-precision (16-bit Float) |
| to_float | Change value to Float (32-bit) |
| to_double | Change the value to Double (64-bit) |
- Objects & OOP Instructions for handling class instances and modifying object properties dynamically.
| Opcode | Arguments | Description |
|---|---|---|
| set_prop | prop_name | Set the value of an object property (retrieve value and target_obj from the stack) |
| instantiate | class_name, argc | Creates a new instance of a class with a specified number of constructor arguments |
| inspect_obj | - | Prints the internal structure of an Object to the console |
| inspect_array | - | Print the internal contents of an Array to the console |
Warning
Nightly Opcode: The instantiate instruction is still experimental. The API may change without notice in the @next version.
- Module & Export System Instructions for communication between modules or with external runtimes.
| Opcode | Arguments | Description |
|---|---|---|
| import | module_name, alias_idx | Importing external libraries/modules into a specific variable index |
| export | name | Mark a function or variable to be accessible from outside the VM |
Warning
Nightly Opcode: The export and import instructions are still experimental. The API may change without notice in the @next version.
- Basic I/O & Loop Control Instructions for standard output and more specific iteration control.
| Opcode | Arguments | Description |
|---|---|---|
| - | Prints the top value of the stack to the console without a newline | |
| println | - | Prints the top value of the stack to the console with a newline |
| break | target_ip | Stops the loop and jumps to the specified target_ip |
| nop | - | Empty instructions (usually for placeholders or alignment) |
LightVM supports a wide range of platforms and architectures to ensure maximum operational flexibility. Here's the current compatibility list:
| OS / Runtime | Architecture | Toolchain | Rust | Node.js |
|---|---|---|---|---|
| Windows | x64, ia32 | MSVC | ✓ | ✓ |
| Linux | x64, ia32, arm64 | GNU (glibc) | ✓ | ✓ |
| Linux (musl) | x64, ia32, arm64 | musl | ✓ | ✓ |
| macOS (Darwin) | x64 | Apple Clang | ✓ | ✓ |
| Android | arm64, arm | NDK | ✓ | ✓ |
| FreeBSD | x64 | Clang | ✓ | ✓ |
This project is distributed using the Apache-2.0 license