adding disasm option
This commit is contained in:
parent
3807276a55
commit
a21dee61e7
|
@ -3205,7 +3205,10 @@ impl Codegen {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
{
|
{
|
||||||
self.disasm(&mut String::new());
|
let mut vc = Vec::<u8>::new();
|
||||||
|
if self.disasm(&mut vc).is_err() {
|
||||||
|
panic!("{}", String::from_utf8(vc).unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.run_vm();
|
self.run_vm();
|
||||||
|
@ -3223,8 +3226,7 @@ impl Codegen {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
pub fn disasm(&mut self, output: &mut impl std::io::Write) -> std::io::Result<()> {
|
||||||
fn disasm(&mut self, output: &mut String) {
|
|
||||||
use crate::DisasmItem;
|
use crate::DisasmItem;
|
||||||
let mut sluce = self.output.code.as_slice();
|
let mut sluce = self.output.code.as_slice();
|
||||||
let functions = self
|
let functions = self
|
||||||
|
@ -3280,20 +3282,15 @@ impl Codegen {
|
||||||
.map(|s| (s.range.start, ("string", s.range.len() as _, DisasmItem::Global))),
|
.map(|s| (s.range.start, ("string", s.range.len() as _, DisasmItem::Global))),
|
||||||
)
|
)
|
||||||
.collect::<HashMap<_, _>>();
|
.collect::<HashMap<_, _>>();
|
||||||
if crate::disasm(&mut sluce, &functions, output, |bin| {
|
crate::disasm(&mut sluce, &functions, output, |bin| {
|
||||||
if self.ct.active()
|
if self.ct.active()
|
||||||
&& let Some(trap) = Self::read_trap(bin.as_ptr() as u64)
|
&& let Some(trap) = Self::read_trap(bin.as_ptr() as u64)
|
||||||
{
|
{
|
||||||
bin.take(..trap.size() + 1).unwrap();
|
bin.take(..trap.size() + 1).unwrap();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
panic!("{} {:?}", output, sluce);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
fn is_fully_linked(&self, func: ty::Func) -> bool {
|
fn is_fully_linked(&self, func: ty::Func) -> bool {
|
||||||
self.output
|
self.output
|
||||||
.relocs
|
.relocs
|
||||||
|
@ -3471,7 +3468,12 @@ mod tests {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
codegen.dump(&mut out).unwrap();
|
codegen.dump(&mut out).unwrap();
|
||||||
|
|
||||||
codegen.disasm(output);
|
let mut buf = Vec::<u8>::new();
|
||||||
|
let err = codegen.disasm(&mut buf);
|
||||||
|
output.push_str(String::from_utf8(buf).unwrap().as_str());
|
||||||
|
if err.is_err() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
|
|
@ -135,27 +135,25 @@ fn decode<T>(binary: &mut &[u8]) -> Option<T> {
|
||||||
unsafe { Some(std::ptr::read(binary.take(..std::mem::size_of::<T>())?.as_ptr() as *const T)) }
|
unsafe { Some(std::ptr::read(binary.take(..std::mem::size_of::<T>())?.as_ptr() as *const T)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum DisasmItem {
|
enum DisasmItem {
|
||||||
Func,
|
Func,
|
||||||
Global,
|
Global,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
fn disasm(
|
fn disasm(
|
||||||
binary: &mut &[u8],
|
binary: &mut &[u8],
|
||||||
functions: &HashMap<u32, (&str, u32, DisasmItem)>,
|
functions: &HashMap<u32, (&str, u32, DisasmItem)>,
|
||||||
out: &mut String,
|
out: &mut impl std::io::Write,
|
||||||
mut eca_handler: impl FnMut(&mut &[u8]),
|
mut eca_handler: impl FnMut(&mut &[u8]),
|
||||||
) -> std::fmt::Result {
|
) -> std::io::Result<()> {
|
||||||
use self::instrs::Instr;
|
use self::instrs::Instr;
|
||||||
|
|
||||||
fn instr_from_byte(b: u8) -> Result<Instr, std::fmt::Error> {
|
fn instr_from_byte(b: u8) -> std::io::Result<Instr> {
|
||||||
if b as usize >= instrs::NAMES.len() {
|
if b as usize >= instrs::NAMES.len() {
|
||||||
return Err(std::fmt::Error);
|
return Err(std::io::ErrorKind::InvalidData.into());
|
||||||
}
|
}
|
||||||
unsafe { std::mem::transmute(b) }
|
Ok(unsafe { std::mem::transmute::<u8, Instr>(b) })
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut labels = HashMap::<u32, u32>::default();
|
let mut labels = HashMap::<u32, u32>::default();
|
||||||
|
@ -179,7 +177,7 @@ fn disasm(
|
||||||
if offset as u32 == off + len {
|
if offset as u32 == off + len {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
instrs::parse_args(binary, inst, &mut buf).ok_or(std::fmt::Error)?;
|
instrs::parse_args(binary, inst, &mut buf).ok_or(std::io::ErrorKind::OutOfMemory)?;
|
||||||
|
|
||||||
for op in buf.drain(..) {
|
for op in buf.drain(..) {
|
||||||
let rel = match op {
|
let rel = match op {
|
||||||
|
@ -211,18 +209,16 @@ fn disasm(
|
||||||
}
|
}
|
||||||
let prev = *binary;
|
let prev = *binary;
|
||||||
|
|
||||||
use std::fmt::Write;
|
|
||||||
|
|
||||||
writeln!(out, "{name}:")?;
|
writeln!(out, "{name}:")?;
|
||||||
|
|
||||||
binary.take(..off as usize).unwrap();
|
binary.take(..off as usize).unwrap();
|
||||||
while let Some(&byte) = binary.first() {
|
while let Some(&byte) = binary.first() {
|
||||||
let inst = instr_from_byte(byte)?;
|
let inst = instr_from_byte(byte).unwrap();
|
||||||
let offset: i32 = (prev.len() - binary.len()).try_into().unwrap();
|
let offset: i32 = (prev.len() - binary.len()).try_into().unwrap();
|
||||||
if offset as u32 == off + len {
|
if offset as u32 == off + len {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
instrs::parse_args(binary, inst, &mut buf).ok_or(std::fmt::Error)?;
|
instrs::parse_args(binary, inst, &mut buf).unwrap();
|
||||||
|
|
||||||
if let Some(label) = labels.get(&offset.try_into().unwrap()) {
|
if let Some(label) = labels.get(&offset.try_into().unwrap()) {
|
||||||
write!(out, "{:>2}: ", label)?;
|
write!(out, "{:>2}: ", label)?;
|
||||||
|
@ -281,8 +277,12 @@ fn disasm(
|
||||||
*binary = prev;
|
*binary = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_oob || has_cycle {
|
if has_oob {
|
||||||
return Err(std::fmt::Error);
|
return Err(std::io::ErrorKind::InvalidInput.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if has_cycle {
|
||||||
|
return Err(std::io::ErrorKind::TimedOut.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -700,6 +700,7 @@ pub fn run_test(
|
||||||
pub struct Options {
|
pub struct Options {
|
||||||
pub fmt: bool,
|
pub fmt: bool,
|
||||||
pub fmt_current: bool,
|
pub fmt_current: bool,
|
||||||
|
pub dump_asm: bool,
|
||||||
pub extra_threads: usize,
|
pub extra_threads: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,13 +753,17 @@ pub fn run_compiler(
|
||||||
} else if options.fmt_current {
|
} else if options.fmt_current {
|
||||||
let ast = parsed.into_iter().next().unwrap();
|
let ast = parsed.into_iter().next().unwrap();
|
||||||
let source = std::fs::read_to_string(&*ast.path)?;
|
let source = std::fs::read_to_string(&*ast.path)?;
|
||||||
format_to(&ast, &source, &mut std::io::stdout())?;
|
format_to(&ast, &source, out)?;
|
||||||
} else {
|
} else {
|
||||||
let mut codegen = codegen::Codegen::default();
|
let mut codegen = codegen::Codegen::default();
|
||||||
codegen.files = parsed;
|
codegen.files = parsed;
|
||||||
|
|
||||||
codegen.generate();
|
codegen.generate();
|
||||||
codegen.dump(out)?;
|
if options.dump_asm {
|
||||||
|
codegen.disasm(out)?;
|
||||||
|
} else {
|
||||||
|
codegen.dump(out)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -15,6 +15,7 @@ fn main() -> std::io::Result<()> {
|
||||||
hblang::Options {
|
hblang::Options {
|
||||||
fmt: args.contains(&"--fmt"),
|
fmt: args.contains(&"--fmt"),
|
||||||
fmt_current: args.contains(&"--fmt-current"),
|
fmt_current: args.contains(&"--fmt-current"),
|
||||||
|
dump_asm: args.contains(&"--dump-asm"),
|
||||||
extra_threads: args
|
extra_threads: args
|
||||||
.iter()
|
.iter()
|
||||||
.position(|&a| a == "--threads")
|
.position(|&a| a == "--threads")
|
||||||
|
|
|
@ -7,7 +7,7 @@ use {
|
||||||
log,
|
log,
|
||||||
parser::{
|
parser::{
|
||||||
self,
|
self,
|
||||||
idfl::{self, index},
|
idfl::{self},
|
||||||
Expr, ExprRef, FileId, Pos,
|
Expr, ExprRef, FileId, Pos,
|
||||||
},
|
},
|
||||||
HashMap,
|
HashMap,
|
||||||
|
@ -17,7 +17,6 @@ use {
|
||||||
mem,
|
mem,
|
||||||
ops::{self, Range},
|
ops::{self, Range},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
usize,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue