Presentamos Achronyme — un lenguaje para pruebas zero-knowledge. Lee el anuncio

VM y Bytecode

Máquina virtual basada en registros, opcodes y formato binario.

La VM de Achronyme es un intérprete de bytecode basado en registros. Ejecuta archivos .achb compilados usando una pila de tamaño fijo de 65,536 slots de Value.

Arquitectura

Fuente (.ach)


Compilador de Bytecode → Prototipos de función + bytecode


Serializador → archivo binario .achb


Cargador → heap + pila + frames de la VM


Intérprete → Ejecución basada en registros

Estructura de la VM

VM {
    heap: Heap,              // arenas tipadas + GC
    stack: [Value; 65536],   // pila de registros de tamaño fijo
    frames: Vec<CallFrame>,  // pila de llamadas
    globals: Vec<GlobalEntry>,  // variables globales
    natives: Vec<NativeObj>,    // 23 funciones integradas
    open_upvalues: lista enlazada, // variables de pila capturadas
    stress_mode: bool,          // forzar GC en cada ciclo
}

Frames de Llamada

Cada llamada a función apila un CallFrame:

CallFrame {
    closure: u32,   // handle a Closure en el heap
    ip: usize,      // puntero de instrucción
    base: usize,    // offset base en la pila
    dest_reg: usize, // dónde almacenar valor de retorno
}

El registro R[i] en el frame actual mapea a stack[frame.base + i].

Representación de Valores

Los valores son enteros de 64 bits etiquetados — sin boxing para tipos comunes:

Bits 63..60 = etiqueta de 4 bits
Bits 59..0  = payload de 60 bits

Etiquetas

EtiquetaNombrePayload
0INTentero con signo i60 (en línea)
1NIL
2FALSE
3TRUE
4STRINGhandle u32 → arena de strings
5LISThandle u32 → arena de listas
6MAPhandle u32 → arena de mapas
7FUNCTIONhandle u32 → arena de funciones
8FIELDhandle u32 → arena de campos (BN254)
9PROOFhandle u32 → arena de pruebas
10NATIVEhandle u32 → tabla de nativos
11CLOSUREhandle u32 → arena de closures
12ITERhandle u32 → arena de iteradores

Los enteros (etiqueta 0) son el tipo de valor más común — usar la etiqueta 0 significa que no se necesita enmascaramiento para el caso común.

Rango de enteros: -2^59 a 2^59 - 1 (576,460,752,303,423,487). El desbordamiento genera IntegerOverflow.

Codificación de Instrucciones

Cada instrucción es un u32 en uno de dos formatos:

Formato ABC

[opcode:8][A:8][B:8][C:8]

Usado para instrucciones de 3 operandos como Add R[A] = R[B] + R[C].

Formato ABx

[opcode:8][A:8][Bx:16]

Usado para instrucciones con un operando de 16 bits, como LoadConst R[A] = K[Bx] o Jump IP = Bx.

Opcodes

Constantes y Movimientos

OpcodeCódigoFormatoDescripción
LoadConst0ABxR[A] = K[Bx] — cargar del pool de constantes
LoadTrue1AR[A] = true
LoadFalse2AR[A] = false
LoadNil3AR[A] = nil
Move5ABR[A] = R[B]

Aritmética

OpcodeCódigoFormatoDescripción
Add10ABCR[A] = R[B] + R[C]
Sub11ABCR[A] = R[B] - R[C]
Mul12ABCR[A] = R[B] * R[C]
Div13ABCR[A] = R[B] / R[C]
Mod14ABCR[A] = R[B] % R[C]
Pow15ABCR[A] = R[B] ^ R[C]
Neg16ABR[A] = -R[B]

Comparación y Lógica

OpcodeCódigoFormatoDescripción
Eq20ABCR[A] = R[B] == R[C]
Lt21ABCR[A] = R[B] < R[C]
Gt22ABCR[A] = R[B] > R[C]
NotEq23ABCR[A] = R[B] != R[C]
Le24ABCR[A] = R[B] <= R[C]
Ge25ABCR[A] = R[B] >= R[C]
LogNot26ABR[A] = !R[B]

Closures y Upvalues

OpcodeCódigoFormatoDescripción
GetUpvalue34ABR[A] = Upvalue[B]
SetUpvalue35ABUpvalue[B] = R[A]
CloseUpvalue36ACerrar upvalue en slot de pila A

Funciones

OpcodeCódigoFormatoDescripción
Return54ARetornar R[A] del frame actual
Call55ABCR[A] = Call(R[B], R[B+1]..R[B+C-1])
Closure56ABxR[A] = Closure(K[Bx])

Flujo de Control

OpcodeCódigoFormatoDescripción
Jump60BxIP = Bx
JumpIfFalse61ABxSi !R[A] entonces IP = Bx
GetIter65ABR[A] = Iterator(R[B])
ForIter66ABxSiguiente elemento o saltar a Bx

Globales

OpcodeCódigoFormatoDescripción
DefGlobalVar98ABxDefinir global mutable
DefGlobalLet99ABxDefinir global inmutable
GetGlobal100ABxR[A] = Global[K[Bx]]
SetGlobal101ABxGlobal[K[Bx]] = R[A]
Print102AImprimir R[A]

Estructuras de Datos

OpcodeCódigoFormatoDescripción
BuildList150ABCR[A] = [R[B]..R[B+C-1]]
BuildMap151ABCR[A] = {R[B]:R[B+1], ...}
GetIndex152ABCR[A] = R[B][R[C]]
SetIndex153ABCR[A][R[B]] = R[C]

ZK

OpcodeCódigoFormatoDescripción
Prove160Compilar + verificar circuito ZK

Especiales

OpcodeCódigoDescripción
Nop255Sin operación

Objetos de Función

Cada función compilada produce un struct Function en el heap:

Function {
    name: String,        // para depuración
    arity: u8,           // conteo de parámetros
    max_slots: u16,      // uso pico de registros
    chunk: Vec<u32>,     // instrucciones de bytecode
    constants: Vec<Value>, // pool de constantes
    upvalue_info: Vec<u8>, // pares [is_local, index]
    line_info: Vec<u32>, // número de línea por instrucción
}

El vector line_info es paralelo a chunk — cada instrucción tiene un número de línea fuente para reporte de errores.

Formato Binario (.achb)

El formato de archivo .achb (versión 9):

Magic:    b"ACH\x09"          (4 bytes)
Metadata: max_slots (u16 LE)

Global Strings:
    count (u32 LE)
    por cada uno: length (u32 LE) + bytes UTF-8

Global Constants:
    count (u32 LE)
    por cada uno: tag (u8) + payload
        INT (0):    i64 LE
        STRING (1): handle u32 LE
        FIELD (8):  4 × u64 LE (limbs Montgomery)
        NIL (255):  (sin payload)

Prototypes:
    count (u32 LE)
    por cada uno:
        name_len (u32 LE) + bytes del nombre
        arity (u8)
        max_slots (u16 LE)
        const_count (u32 LE) + constantes
        upvalue_count (u32 LE) + info de upvalue
        bytecode_len (u32 LE) + instrucciones (u32 LE cada una)

Main Bytecode:
    instruction_count (u32 LE)
    instrucciones (u32 LE cada una)

El formato es compatible con el módulo loader de la VM, que deserializa en objetos del heap.

Disposición de Variables Globales

Índice: 0..22       23..
        Nativos     Globales de usuario

Los primeros 23 slots (0–22) están reservados para funciones nativas. Las globales definidas por el usuario comienzan en el índice 23 (USER_GLOBAL_START).

Archivos Fuente

ComponenteArchivo
Opcodesvm/src/opcode.rs
Intérprete VMvm/src/machine/vm.rs
Frames de llamadavm/src/machine/frame.rs
Despacho de nativosvm/src/specs.rs
Codificación de valoresmemory/src/value.rs
Struct Functionmemory/src/heap.rs
Compilador de bytecodecompiler/src/codegen.rs
Compilador de funcionescompiler/src/function_compiler.rs
Serializador binariocli/src/commands/compile.rs
Cargador binariovm/src/loader.rs
Navigation