feat!: add Rego Virtual Machine (RVM) implementation (#495)

* feat!: add Rego Virtual Machine (RVM) implementation

This commit introduces a register-based virtual machine for executing Rego
policies with bytecode-style instructions. Unlike the existing tree-walking
interpreter, the RVM compiles policies into instruction sequences that operate
on virtual registers, offering better performance and optimization potential.

Core Components:

Instruction Set Architecture:
- Define instruction types for data operations, control flow, and builtins
- Implement instruction parameter encoding and display formatting
- Add instruction parser with comprehensive test coverage

Virtual Machine Engine:
- Register-based execution model with program counter management
- Loop execution supporting iterators, comprehensions, and quantifiers
- Function call handling with argument evaluation and context management
- Rule evaluation with default value resolution and virtual data support
- Arithmetic and comparison operation implementations

Program Representation:
- Program listing builder with instruction sequencing
- Rule tree construction for organizing policy rules
- Binary and JSON serialization for compiled programs
- Recompilation support for program modification

Testing Infrastructure:
- Extensive YAML test suites covering all VM features
- Rust unit tests for VM execution and instruction parsing
- Test suites for loops, comprehensions, builtins, and control flow

BREAKING CHANGE: Introduces new VM execution path alongside interpreter

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

* docs: add detailed RVM architecture references

Introduce architecture.md explaining program artifacts, serialization, and runtime subsystems.
Document the full opcode catalog in instruction-set.md, including operands, parameter tables, and outcomes.
Walk through execution flow, stacks, and operational guidance in vm-runtime.md, tying the runtime to the new architecture docs.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

---------

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2025-11-14 11:43:19 -06:00
committed by GitHub
parent 6dc505c88b
commit 49bd3c22f3
89 changed files with 19158 additions and 313 deletions
+121
View File
@@ -0,0 +1,121 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use crate::value::Value;
use alloc::string::String;
use alloc::vec::Vec;
use thiserror::Error;
/// VM execution errors
#[derive(Error, Debug, Clone, PartialEq)]
pub enum VmError {
#[error("Execution stopped: exceeded maximum instruction limit of {limit}")]
InstructionLimitExceeded { limit: usize },
#[error("Literal index {index} out of bounds")]
LiteralIndexOutOfBounds { index: usize },
#[error("Register {register} does not contain an object")]
RegisterNotObject { register: u8 },
#[error("ObjectCreate: template is not an object")]
ObjectCreateInvalidTemplate,
#[error("Register {register} does not contain an array")]
RegisterNotArray { register: u8 },
#[error("Register {register} does not contain a set")]
RegisterNotSet { register: u8 },
#[error("Rule index {index} out of bounds")]
RuleIndexOutOfBounds { index: u16 },
#[error("Rule index {index} has no info")]
RuleInfoMissing { index: u16 },
#[error("Invalid object create params index: {index}")]
InvalidObjectCreateParams { index: u16 },
#[error("Invalid template literal index: {index}")]
InvalidTemplateLiteralIndex { index: u16 },
#[error("Invalid chained index params index: {index}")]
InvalidChainedIndexParams { index: u16 },
#[error("Invalid array create params index: {index}")]
InvalidArrayCreateParams { index: u16 },
#[error("Invalid set create params index: {index}")]
InvalidSetCreateParams { index: u16 },
#[error("Invalid virtual data document lookup params index: {index}")]
InvalidVirtualDataDocumentLookupParams { index: u16 },
#[error("Invalid comprehension start params index: {index}")]
InvalidComprehensionBeginParams { index: u16 },
#[error("Invalid rule index: {rule_index:?}")]
InvalidRuleIndex { rule_index: Value },
#[error("Invalid rule tree entry: {value:?}")]
InvalidRuleTreeEntry { value: Value },
#[error("Builtin function expects exactly {expected} arguments, got {actual}")]
BuiltinArgumentMismatch { expected: u16, actual: usize },
#[error("Builtin function not resolved: {name}")]
BuiltinNotResolved { name: String },
#[error("Cannot add {left:?} and {right:?}")]
InvalidAddition { left: Value, right: Value },
#[error("Cannot subtract {left:?} and {right:?}")]
InvalidSubtraction { left: Value, right: Value },
#[error("Cannot multiply {left:?} and {right:?}")]
InvalidMultiplication { left: Value, right: Value },
#[error("Cannot divide {left:?} and {right:?}")]
InvalidDivision { left: Value, right: Value },
#[error("modulo on floating-point number")]
ModuloOnFloat,
#[error("Cannot modulo {left:?} and {right:?}")]
InvalidModulo { left: Value, right: Value },
#[error("Cannot iterate over {value:?}")]
InvalidIteration { value: Value },
#[error("HostAwait executed but no response provided for destination register {dest} (id: {identifier:?})")]
HostAwaitResponseMissing { dest: u8, identifier: Value },
#[error("Assertion failed")]
AssertionFailed,
#[error("Rule-data conflict: {0}")]
RuleDataConflict(String),
#[error("Arithmetic error: {0}")]
ArithmeticError(String),
#[error("Entry point index {index} out of bounds (max: {max_index})")]
InvalidEntryPointIndex { index: usize, max_index: usize },
#[error("Entry point '{name}' not found. Available entry points: {available:?}")]
EntryPointNotFound {
name: String,
available: Vec<String>,
},
#[error("Internal VM error: {0}")]
Internal(String),
}
impl From<anyhow::Error> for VmError {
fn from(err: anyhow::Error) -> Self {
VmError::ArithmeticError(alloc::format!("{}", err))
}
}
pub type Result<T> = core::result::Result<T, VmError>;