prometeu-bytecode
Contrato oficial (ABI) do ecossistema PROMETEU. Este crate define o conjunto de instruções (ISA), o formato de arquivo .pbc (Prometeu ByteCode) e ferramentas básicas de montagem (Assembler) e desmontagem (Disassembler).
Design
A PVM (Prometeu Virtual Machine) é uma máquina baseada em pilha (stack-based). A maioria das instruções opera nos valores do topo da pilha de operandos. O formato de dados padrão para multi-byte na ROM é Little-Endian.
Convenção de Notação da Pilha
Nas tabelas abaixo, usamos a seguinte notação para representar o estado da pilha:
[a, b] -> [c]
Significa que a instrução remove a e b da pilha (onde b estava no topo) e insere c no topo.
Conjunto de Instruções (ISA)
6.1 Controle de Execução
| OpCode |
Valor |
Operandos |
Pilha |
Descrição |
Nop |
0x00 |
- |
[] -> [] |
Nenhuma operação. |
Halt |
0x01 |
- |
[] -> [] |
Interrompe a execução da VM permanentemente. |
Jmp |
0x02 |
addr: u32 |
[] -> [] |
Salto incondicional para o endereço absoluto addr. |
JmpIfFalse |
0x03 |
addr: u32 |
[bool] -> [] |
Salta para addr se o valor desempilhado for false. |
JmpIfTrue |
0x04 |
addr: u32 |
[bool] -> [] |
Salta para addr se o valor desempilhado for true. |
Trap |
0x05 |
- |
[] -> [] |
Interrupção para debugger (breakpoint). |
6.2 Manipulação da Pilha
| OpCode |
Valor |
Operandos |
Pilha |
Descrição |
PushConst |
0x10 |
idx: u32 |
[] -> [val] |
Carrega a constante do índice idx da Constant Pool. |
Pop |
0x11 |
- |
[val] -> [] |
Remove e descarta o valor do topo da pilha. |
Dup |
0x12 |
- |
[val] -> [val, val] |
Duplica o valor no topo da pilha. |
Swap |
0x13 |
- |
[a, b] -> [b, a] |
Inverte a posição dos dois valores no topo. |
PushI64 |
0x14 |
val: i64 |
[] -> [i64] |
Empilha um inteiro de 64 bits imediato. |
PushF64 |
0x15 |
val: f64 |
[] -> [f64] |
Empilha um ponto flutuante de 64 bits imediato. |
PushBool |
0x16 |
val: u8 |
[] -> [bool] |
Empilha um booleano (0=false, 1=true). |
PushI32 |
0x17 |
val: i32 |
[] -> [i32] |
Empilha um inteiro de 32 bits imediato. |
PopN |
0x18 |
n: u16 |
[...] -> [...] |
Remove n valores da pilha de uma vez. |
6.3 Aritmética
A VM realiza promoção automática de tipos (ex: i32 + f64 resulta em f64).
| OpCode |
Valor |
Pilha |
Descrição |
Add |
0x20 |
[a, b] -> [a + b] |
Soma os dois valores do topo. |
Sub |
0x21 |
[a, b] -> [a - b] |
Subtrai b de a. |
Mul |
0x22 |
[a, b] -> [a * b] |
Multiplica os dois valores do topo. |
Div |
0x23 |
[a, b] -> [a / b] |
Divide a por b. Erro se b == 0. |
Neg |
0x3E |
[a] -> [-a] |
Inverte o sinal numérico. |
6.4 Lógica e Comparação
| OpCode |
Valor |
Pilha |
Descrição |
Eq |
0x30 |
[a, b] -> [bool] |
Testa igualdade. |
Neq |
0x31 |
[a, b] -> [bool] |
Testa desigualdade. |
Lt |
0x32 |
[a, b] -> [bool] |
a < b |
Gt |
0x33 |
[a, b] -> [bool] |
a > b |
Lte |
0x3C |
[a, b] -> [bool] |
a <= b |
Gte |
0x3D |
[a, b] -> [bool] |
a >= b |
And |
0x34 |
[a, b] -> [bool] |
AND lógico (booleano). |
Or |
0x35 |
[a, b] -> [bool] |
OR lógico (booleano). |
Not |
0x36 |
[a] -> [!a] |
NOT lógico. |
BitAnd |
0x37 |
[a, b] -> [int] |
AND bit a bit. |
BitOr |
0x38 |
[a, b] -> [int] |
OR bit a bit. |
BitXor |
0x39 |
[a, b] -> [int] |
XOR bit a bit. |
Shl |
0x3A |
[a, b] -> [int] |
Shift Left: a << b. |
Shr |
0x3B |
[a, b] -> [int] |
Shift Right: a >> b. |
6.5 Variáveis e Memória
| OpCode |
Valor |
Operandos |
Pilha |
Descrição |
GetGlobal |
0x40 |
idx: u32 |
[] -> [val] |
Carrega valor da global idx. |
SetGlobal |
0x41 |
idx: u32 |
[val] -> [] |
Armazena topo na global idx. |
GetLocal |
0x42 |
idx: u32 |
[] -> [val] |
Carrega local idx do frame atual. |
SetLocal |
0x43 |
idx: u32 |
[val] -> [] |
Armazena topo na local idx do frame atual. |
6.6 Funções e Escopo
| OpCode |
Valor |
Operandos |
Pilha |
Descrição |
Call |
0x50 |
addr: u32, args: u32 |
[a1, a2] -> [...] |
Chama addr. Os args valores no topo viram locais do novo frame. |
Ret |
0x51 |
- |
[val] -> [val] |
Retorna da função atual, limpando o frame e devolvendo o valor do topo. |
PushScope |
0x52 |
- |
[] -> [] |
Inicia um sub-escopo (bloco) para locais temporários. |
PopScope |
0x53 |
- |
[] -> [] |
Finaliza sub-escopo, removendo locais criados nele da pilha. |
6.7 Heap (Memória Dinâmica)
| OpCode |
Valor |
Operandos |
Pilha |
Descrição |
Alloc |
0x60 |
size: u32 |
[] -> [ref] |
Aloca size slots no heap e retorna uma referência. |
LoadRef |
0x61 |
offset: u32 |
[ref] -> [val] |
Lê valor do heap no endereço ref + offset. |
StoreRef |
0x62 |
offset: u32 |
[ref, val] -> [] |
Escreve val no heap no endereço ref + offset. |
6.8 Sistema e Sincronização
| OpCode |
Valor |
Operandos |
Pilha |
Descrição |
Syscall |
0x70 |
id: u32 |
[...] -> [...] |
Invoca uma função do sistema/firmware. A pilha depende da syscall. |
FrameSync |
0x80 |
- |
[] -> [] |
Marca o fim do processamento do frame lógico atual (60 FPS). |
Estrutura do PBC (Prometeu ByteCode)
O PBC é o formato binário oficial para programas Prometeu.
// Exemplo de como carregar um arquivo PBC
let bytes = std::fs::read("game.pbc")?;
let pbc = prometeu_bytecode::pbc::parse_pbc(&bytes)?;
println!("ROM size: {} bytes", pbc.rom.len());
println!("Constants: {}", pbc.cp.len());
Assembler e Disassembler
Este crate fornece ferramentas para facilitar a geração e inspeção de código.
Montagem (Assembler)
use prometeu_bytecode::asm::{assemble, Asm, Operand};
use prometeu_bytecode::opcode::OpCode;
let instructions = vec![
Asm::Op(OpCode::PushI32, vec![Operand::I32(10)]),
Asm::Op(OpCode::PushI32, vec![Operand::I32(20)]),
Asm::Op(OpCode::Add, vec![]),
Asm::Op(OpCode::Halt, vec![]),
];
let rom_bytes = assemble(&instructions).unwrap();
Desmontagem (Disassembler)
use prometeu_bytecode::disasm::disasm;
let rom = vec![/* ... bytes ... */];
let code = disasm(&rom);
for instr in code {
println!("{:04X}: {:?} {:?}", instr.pc, instr.opcode, instr.operands);
}