Added magic

replace/247b2c6614ab81925e96744398632e3b7bb8b7ad
Erin 2023-08-01 22:13:22 +02:00
parent a667c36d6c
commit 1a5f101719
4 changed files with 33 additions and 9 deletions

View File

@ -1,11 +1,11 @@
//! Holey Bytes Assembler //! Holey Bytes Assembler
//! //!
//! Some people claim: //! Some people claim:
//! > Write programs to handle text streams, because that is a universal interface. //! > Write programs to handle text streams, because that is a universal interface.
//! //!
//! We at AbleCorp believe that nice programatic API is nicer than piping some text //! We at AbleCorp believe that nice programatic API is nicer than piping some text
//! into a program. It's less error-prone and faster. //! into a program. It's less error-prone and faster.
//! //!
//! So this crate contains both assembleer with API for programs and a text assembler //! So this crate contains both assembleer with API for programs and a text assembler
//! for humans to write //! for humans to write
@ -15,26 +15,37 @@ extern crate alloc;
mod macros; mod macros;
use {alloc::vec::Vec, hashbrown::HashSet}; use {
alloc::{vec, vec::Vec},
hashbrown::HashSet,
};
/// Assembler /// Assembler
/// ///
/// - Opcode-generic, instruction-type-specific methods are named `i_param_<type>` /// - Opcode-generic, instruction-type-specific methods are named `i_param_<type>`
/// - You likely won't need to use them, but they are here, just in case :) /// - You likely won't need to use them, but they are here, just in case :)
/// - Instruction-specific methods are named `i_<instruction>` /// - Instruction-specific methods are named `i_<instruction>`
#[derive(Default)]
pub struct Assembler { pub struct Assembler {
pub buf: Vec<u8>, pub buf: Vec<u8>,
pub sub: HashSet<usize>, pub sub: HashSet<usize>,
} }
impl Default for Assembler {
fn default() -> Self {
Self {
buf: vec![0; 3],
sub: Default::default(),
}
}
}
hbbytecode::invoke_with_def!(macros::text::gen_text); hbbytecode::invoke_with_def!(macros::text::gen_text);
impl Assembler { impl Assembler {
hbbytecode::invoke_with_def!(macros::asm::impl_asm); hbbytecode::invoke_with_def!(macros::asm::impl_asm);
/// Append 12 zeroes (UN) at the end /// Append 12 zeroes (UN) at the end and add magic to the begining
/// ///
/// # HoleyBytes lore /// # HoleyBytes lore
/// ///
/// In reference HBVM implementation checks are done in /// In reference HBVM implementation checks are done in
@ -61,11 +72,12 @@ impl Assembler {
/// Why 12 bytes? That's the size of largest instruction parameter part. /// Why 12 bytes? That's the size of largest instruction parameter part.
pub fn finalise(&mut self) { pub fn finalise(&mut self) {
self.buf.extend([0; 12]); self.buf.extend([0; 12]);
self.buf[0..3].copy_from_slice(&[0xAB, 0x1E, 0x0B]);
} }
} }
/// Immediate value /// Immediate value
/// ///
/// # Implementor notice /// # Implementor notice
/// It should insert exactly 8 bytes, otherwise output will be malformed. /// It should insert exactly 8 bytes, otherwise output will be malformed.
/// This is not checked in any way /// This is not checked in any way

View File

@ -23,6 +23,8 @@ macro_rules! gen_valider {
RegisterArrayOverflow, RegisterArrayOverflow,
/// Program is not validly terminated /// Program is not validly terminated
InvalidEnd, InvalidEnd,
/// Program misses magic
MissingMagic
} }
/// Error /// Error
@ -37,6 +39,14 @@ macro_rules! gen_valider {
/// Perform bytecode validation. If it passes, the program should be /// Perform bytecode validation. If it passes, the program should be
/// sound to execute. /// sound to execute.
pub fn validate(mut program: &[u8]) -> Result<(), Error> { pub fn validate(mut program: &[u8]) -> Result<(), Error> {
// Validate magic
if program.get(0..3) != Some(&[0xAB, 0x1E, 0x0B]) {
return Err(Error {
kind: ErrorKind::MissingMagic,
index: 0,
});
}
// Program has to end with 12 zeroes, if there is less than // Program has to end with 12 zeroes, if there is less than
// 12 bytes, program is invalid. // 12 bytes, program is invalid.
if program.len() < 12 { if program.len() < 12 {
@ -57,6 +67,7 @@ macro_rules! gen_valider {
} }
let start = program; let start = program;
program = &program[3..];
loop { loop {
use crate::opcode::*; use crate::opcode::*;
program = match program { program = match program {

View File

@ -73,7 +73,7 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize>
pfhandler: traph, pfhandler: traph,
pc: 0, pc: 0,
program_len: program.len() - 12, program_len: program.len() - 12,
program, program: &program[3..],
timer: 0, timer: 0,
copier: None, copier: None,
} }

View File

@ -1,6 +1,7 @@
# HoleyBytes ISA Specification # HoleyBytes ISA Specification
# Bytecode format # Bytecode format
- Holey Bytes program should start with following magic: `0xAB1E0B`
- All numbers are encoded little-endian - All numbers are encoded little-endian
- There is 256 registers, they are represented by a byte - There is 256 registers, they are represented by a byte
- Immediate values are 64 bit - Immediate values are 64 bit