Skip to content

At0mXploit/Eva-VM

Repository files navigation

Eva VM

A stack based bytecode virtual machine for the Eva programming language, implemented in Python using a functional programming approach like Lisp (no classes/OOP in the VM).

Overview

This is a complete rewrite of the Eva VM from C++ to Python, using:

  • Dictionaries and lists instead of classes
  • Pure functions instead of methods
  • Functional composition for program flow
  • Simple, readable code structure

Architecture

Core Components

  1. eva_value.py - Value system (numbers, booleans, strings, objects)
  2. opcodes.py - Bytecode instruction definitions
  3. parser.py - S-expression parser
  4. scope.py - Lexical scope analysis
  5. compiler_helpers.py - Helper functions for compilation
  6. compiler.py - AST to bytecode compiler
  7. vm.py - Virtual machine and execution engine
  8. eva-vm.py - Main entry point

Features

  • Arithmetic operations (+, -, *, /)
  • Comparison operations (<, >, ==, >=, <=, !=)
  • Variables (global and local)
  • Functions and closures
  • Control flow (if, while)
  • Classes and inheritance
  • Object properties
  • Lexical scoping with cells (for closures)

Installation

No installation required! Just needs Python 3.6+

chmod +x eva-vm.py

Usage

Run an expression:

python3 eva-vm.py -e "(+ 1 2)"

Run a file:

python3 eva-vm.py -f test.eva

Show bytecode disassembly:

python3 eva-vm.py -e "(def square (x) (* x x)) (square 5)" -d

Eva Language Examples

1. Basic Arithmetic

(+ 2 3)              ; => 5
(* (+ 2 3) 4)        ; => 20

2. Variables

(var x 10)
(var y 20)
(+ x y)              ; => 30

3. Functions

(def square (x)
  (* x x))

(square 5)           ; => 25

4. Closures

(def makeCounter (start)
  (begin
    (var count start)
    (lambda ()
      (begin
        (set count (+ count 1))
        count))))

(var counter (makeCounter 0))
(counter)            ; => 1
(counter)            ; => 2
(counter)            ; => 3

5. Control Flow

; If statement
(if (> 10 5)
  "yes"
  "no")              ; => "yes"

; While loop
(var i 0)
(while (< i 5)
  (set i (+ i 1)))   ; i becomes 5

6. Classes and Inheritance

(class Point null
  (def constructor (self x y)
    (begin
      (set (prop self x) x)
      (set (prop self y) y)))

  (def calc (self)
    (+ (prop self x) (prop self y))))

(class Point3D Point
  (def constructor (self x y z)
    (begin
      ((prop (super Point3D) constructor) self x y)
      (set (prop self z) z)))

  (def calc (self)
    (+ ((prop (super Point3D) calc) self) (prop self z))))

(var p (new Point3D 10 20 30))
((prop p calc) p)    ; => 60

How It Works

1. Parsing

The parser converts S-expressions into a simple AST:

  • Numbers → integers
  • Strings → strings (without quotes)
  • Symbols → strings
  • Lists → Python lists

2. Scope Analysis

Before compilation, the analyzer:

  • Identifies all variable declarations
  • Determines variable allocation (global, local, or cell)
  • Promotes captured variables to heap-allocated cells
  • Tracks free variables for closures

3. Compilation

The compiler walks the AST and:

  • Generates bytecode instructions
  • Builds constant pools
  • Creates code objects for functions
  • Handles lexical scoping

4. Execution

The VM:

  • Uses a stack for operands and local variables
  • Uses a call stack for function frames
  • Executes bytecode instructions sequentially
  • Manages closures via heap-allocated cells

Value Representation

All values are dictionaries with a 'type' field:

# Number
{'type': 'NUMBER', 'value': 42}

# Boolean
{'type': 'BOOLEAN', 'value': True}

# String object
{'type': 'OBJECT', 'obj_type': 'STRING', 'value': 'hello'}

# Function object
{'type': 'OBJECT', 'obj_type': 'FUNCTION', 'code': {...}, 'cells': [...]}

Bytecode Instructions

The VM uses a compact bytecode format:

Opcode Name Description
0x00 HALT Stop execution
0x01 CONST Push constant
0x02 ADD Add two values
0x03 SUB Subtract
0x04 MUL Multiply
0x05 DIV Divide
0x06 COMPARE Compare values
0x07 JMP_IF_FALSE Conditional jump
0x08 JMP Unconditional jump
0x09 GET_GLOBAL Get global variable
0x0A SET_GLOBAL Set global variable
0x0B POP Pop stack
0x0C GET_LOCAL Get local variable
0x0D SET_LOCAL Set local variable
0x0E SCOPE_EXIT Clean up scope
0x0F CALL Call function
0x10 RETURN Return from function
0x11 GET_CELL Get cell variable
0x12 SET_CELL Set cell variable
0x13 LOAD_CELL Load cell for closure
0x14 MAKE_FUNCTION Create closure
0x15 NEW Create instance
0x16 GET_PROP Get property
0x17 SET_PROP Set property

Key Design Decisions

1. No Classes/OOP

Instead of classes, we use:

  • Dictionaries for structured data
  • Functions for operations
  • Closures for encapsulation

2. Explicit State Passing

VM state is explicitly passed to functions:

def push(vm, value):
    vm['stack'][vm['sp']] = value
    vm['sp'] += 1

3. Functional Composition

Complex operations are built from simple functions:

def gen(state, exp):
    if is_number_ast(exp):
        emit(state['co'], OP_CONST)
        emit(state['co'], alloc_numeric_const(state['co'], exp))

4. Immutable Constants

The original C++ code uses static constants. In Python, we use module-level constants:

OP_HALT = 0x00
OP_CONST = 0x01
# ...

Testing

# Simple math
python3 eva-vm.py -e "(+ 2 3)"
# Output: 5

# Functions
python3 eva-vm.py -e "(def square (x) (* x x)) (square 5)"
# Output: 25

# Factorial
python3 eva-vm.py -f examples/factorial.eva
# Output: 120

# Closures
python3 eva-vm.py -f examples/closure.eva
# Output: 13

# Fibonacci
python3 eva-vm.py -f examples/fibonacci.eva
# Output: 55

# Classes
python3 eva-vm.py -f examples/class.eva
# Output: 50

# Class inheritance (original test)
python3 eva-vm.py -f test.eva
# Output: 60

Run the test file:

python3 eva-vm.py -f test.eva

Should output: 60

Run with disassembly to see bytecode:

python3 eva-vm.py -f test.eva -d

Performance

This implementation prioritizes:

  1. Readability over performance
  2. Simplicity over optimization
  3. Learning over production use

For production use, consider:

  • PyPy for JIT compilation
  • Cython for C-level performance
  • Or stick with the original C++ version

Credits

Based on the Eva VM course by Dmitry Soshnikov: http://dmitrysoshnikov.com/courses/virtual-machine/

Original C++ implementation: https://github.com/DmitrySoshnikov/eva-vm

Pwn College Yan85 emulator from it's Reverse Engineering Dojo.


About

A stack based bytecode Virtual Machine.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages