pybevy_bytecodevm 0.2.0

Bytecode VM for PyBevy expressions
Documentation
# pybevy_bytecodevm

A high-performance bytecode virtual machine for executing lazy mathematical expressions on ECS component fields in batch operations.

## Overview

`pybevy_bytecodevm` is a stack-based bytecode compiler and interpreter designed for minimal overhead execution of mathematical expressions across large numbers of entities in the Bevy ECS. It powers PyBevy's View API, enabling 30-50x performance improvements over traditional Python Query iteration.

## Features

- **Stack-based VM**: Simple, cache-friendly bytecode execution (~2-5ns per operation)
- **Expression AST**: Parse Python expressions into an optimizable intermediate representation
- **Bytecode Compilation**: Convert expression trees to linear bytecode with constant folding
- **Type Support**: Multiple field types (f32, f64, i32, i64, u32, u64, bool) with f64 internal precision
- **Rich Operations**: Arithmetic, trigonometric, comparison, logical, and random operations
- **Deterministic Random**: Per-entity seeded randomness for reproducible simulations
- **Reduction Mode**: Evaluate expressions without storing results (for filtering/aggregation)

## Architecture

```
Python Expression → RustExpr AST → Compiler → CompiledBytecode → VM Execution
```

### Components

1. **`RustExpr`** (`expr.rs`): Abstract Syntax Tree representing mathematical expressions
2. **`Compiler`** (`bytecode.rs`): Converts AST to optimized bytecode with constant pool
3. **`VM`** (`bytecode.rs`): Executes bytecode on entity component data
4. **`CompiledBytecode`** (`bytecode.rs`): Compiled bytecode ready for execution

## Performance

The bytecode VM is optimized for:

- **Cache locality**: Linear bytecode array (no tree traversal)
- **Minimal overhead**: Simple stack operations with no recursion
- **Parallel execution**: Read-only bytecode perfect for `par_iter_mut`
- **Pre-resolved offsets**: Component field locations computed at compile time

## Example Usage

### Compiling an Expression

```rust
use pybevy_bytecodevm::{Compiler, RustExpr, Op};

// Expression: pos.x = pos.x + vel.x * dt
let mut compiler = Compiler::new();

// Build expression AST
let expr = RustExpr::Add(
    Box::new(RustExpr::Field { /* pos.x */ }),
    Box::new(RustExpr::Mul(
        Box::new(RustExpr::Field { /* vel.x */ }),
        Box::new(RustExpr::Const(dt))
    ))
);

// Compile to bytecode
expr.compile(&mut compiler);
compiler.optimize(); // Apply peephole optimizations
let bytecode = compiler.finalize();
```

### Executing Bytecode

```rust
use pybevy_bytecodevm::VM;

let mut vm = VM::new();

// field_ptrs: one pointer per field registered with the compiler,
// pointing to the field's memory for this entity.
// entity_index: the entity's index, used for deterministic random seeding.
let mut pos_x: f32 = 100.0;
let mut vel_x: f32 = 5.0;
let field_ptrs: &[*mut u8] = &[
    &mut pos_x as *mut f32 as *mut u8,  // field 0: pos.x
    &mut vel_x as *mut f32 as *mut u8,  // field 1: vel.x
];
let entity_index: usize = 42;

unsafe {
    vm.execute(&bytecode, field_ptrs, entity_index);
}
// pos_x is now updated in-place
```

### Reduction Mode

```rust
// Evaluate an expression and return the result without storing.
// Useful for filtering or aggregation.
let mut health: f32 = 30.0;
let field_ptrs: &[*mut u8] = &[
    &mut health as *mut f32 as *mut u8,  // field 0: health
];
let entity_index: usize = 7;

let result = unsafe {
    vm.execute_and_reduce(&bytecode, field_ptrs, entity_index)
};
// result contains the final stack value (e.g. a boolean comparison result as 0.0/1.0)
```

## Bytecode Example

Expression: `pos.x = pos.x + vel.x * dt`

Bytecode:
```
PushField(0)      // Push pos.x
PushField(1)      // Push vel.x
PushConst(0)      // Push dt from constant pool
Mul               // vel.x * dt
Add               // pos.x + (vel.x * dt)
StoreField(0)     // Store to pos.x
```

## Supported Operations

### Arithmetic
- Add, Sub, Mul, Div, Pow, Neg, Mod

### Trigonometric
- Sin, Cos, Tan, Asin, Acos, Atan

### Numeric
- Sqrt, Abs, Floor, Ceil, Round, Min, Max, Clamp
- Exp, Ln, Log10, Log2, Sign, Fract, Lerp

### Comparison
- Eq, Ne, Lt, Le, Gt, Ge

### Logical
- And, Or, Not

### Conditional
- Where (ternary operator: `where(condition, true_value, false_value)`)

### Random
- Random (deterministic per-entity [0.0, 1.0))
- RandomRange (deterministic per-entity [min, max))

## Optimizations

The compiler applies peephole optimizations including:

- **Constant folding**: `5.0 + 3.0``8.0` at compile time
- **Constant deduplication**: Shared constant pool with bit-exact matching

## Integration with PyBevy

This crate is used internally by PyBevy's View API:

```python
# Python code
view = View[tuple[Mut[Transform], Velocity]]
pos = view.column_mut(Transform)
vel = view.column(Velocity)

# Compiles to bytecode and executes via VM
pos.translation.x = pos.translation.x + vel.x * dt
```

## Safety

The VM uses `unsafe` for direct memory access to component fields. Callers must ensure:

- All field pointers are valid and properly aligned
- Field pointers remain valid for the duration of execution
- No concurrent mutations to the same memory

These safety requirements are guaranteed by Bevy's ECS query system.

## Testing

Run the test suite:

```bash
cargo test -p pybevy_bytecodevm
```

The crate includes comprehensive tests for:
- Arithmetic operations
- Trigonometric functions
- Comparison operators
- Logical operators
- Conditional selection
- Constant folding optimization
- Field storage and retrieval