//! This module defines the Application Binary Interface (ABI) of the Prometeu Virtual Machine. //! It specifies how instructions are encoded in bytes and how they interact with memory. use crate::opcode::OpCode; /// Returns the size in bytes of the operands for a given OpCode. /// /// Note: This does NOT include the 2 bytes of the OpCode itself. /// For example, `PushI32` has a size of 4, but occupies 6 bytes in ROM (2 for OpCode + 4 for value). pub fn operand_size(opcode: OpCode) -> usize { match opcode { OpCode::PushConst => 4, OpCode::PushI32 => 4, OpCode::PushI64 => 8, OpCode::PushF64 => 8, OpCode::PushBool => 1, OpCode::PopN => 4, OpCode::Jmp | OpCode::JmpIfFalse | OpCode::JmpIfTrue => 4, OpCode::GetGlobal | OpCode::SetGlobal => 4, OpCode::GetLocal | OpCode::SetLocal => 4, OpCode::Call => 8, // addr(u32) + args_count(u32) OpCode::Syscall => 4, _ => 0, } } /// Checks if an instruction is a jump (branch) instruction. pub fn is_jump(opcode: OpCode) -> bool { match opcode { OpCode::Jmp | OpCode::JmpIfFalse | OpCode::JmpIfTrue => true, _ => false, } } /// Checks if an instruction has any immediate operands in the instruction stream. pub fn has_immediate(opcode: OpCode) -> bool { operand_size(opcode) > 0 }