forked from AbleOS/holey-bytes
Added magic
This commit is contained in:
parent
a667c36d6c
commit
1a5f101719
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
1
spec.md
1
spec.md
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue