ppc750cl/disasm-py/src/lib.rs

96 lines
2.1 KiB
Rust
Raw Normal View History

2021-08-16 15:40:13 -07:00
use pyo3::prelude::*;
2021-08-18 16:13:19 -07:00
use pyo3::types::PyBytes;
2021-08-16 15:40:13 -07:00
use pyo3::{PyIterProtocol, PyObjectProtocol};
use ppc750cl::formatter::FormattedIns;
2021-08-16 15:40:13 -07:00
#[pyclass]
struct Ins(ppc750cl::Ins);
#[pymethods]
impl Ins {
#[new]
fn new(code: u32, addr: u32) -> Self {
Ins(ppc750cl::Ins::new(code, addr))
}
#[getter]
fn code(&self) -> PyResult<u32> {
Ok(self.0.code)
}
#[getter]
fn addr(&self) -> PyResult<u32> {
Ok(self.0.addr)
}
}
impl From<ppc750cl::Ins> for Ins {
fn from(ins: ppc750cl::Ins) -> Self {
Self(ins)
}
}
#[pyproto]
impl<'a> PyObjectProtocol<'a> for Ins {
fn __str__(&self) -> String {
FormattedIns(self.0.clone()).to_string()
2021-08-16 15:40:13 -07:00
}
}
#[pyclass]
struct DisasmIterator {
2021-08-18 16:13:19 -07:00
bytes: Py<PyBytes>,
2021-08-16 15:40:13 -07:00
addr: u32,
offset: u32,
2021-08-18 16:13:19 -07:00
left: usize,
2021-08-16 15:40:13 -07:00
}
#[pyproto]
impl PyIterProtocol for DisasmIterator {
fn __iter__(slf: PyRef<Self>) -> PyRef<DisasmIterator> {
slf
}
fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<Ins>> {
2021-08-18 16:13:19 -07:00
if slf.left < 4 {
2021-08-16 15:40:13 -07:00
return Ok(None);
}
2021-08-18 16:13:19 -07:00
let bytes = slf.bytes.as_ref(slf.py());
let code = ((bytes[(slf.offset) as usize] as u32) << 24)
| ((bytes[(slf.offset + 1) as usize] as u32) << 16)
| ((bytes[(slf.offset + 2) as usize] as u32) << 8)
| (bytes[(slf.offset + 3) as usize] as u32);
2021-08-16 15:40:13 -07:00
slf.offset += 4;
2021-08-18 16:13:19 -07:00
slf.left -= 4;
2021-08-16 15:40:13 -07:00
let ins = Ins::new(code, slf.addr);
slf.addr += 4;
Ok(Some(ins))
}
}
#[pyfunction(code, addr, offset = "0", size = "None")]
2021-08-18 16:13:19 -07:00
fn disasm_iter(
code: &PyBytes,
addr: u32,
offset: u32,
size: Option<u32>,
) -> PyResult<DisasmIterator> {
let left = match size {
None => code.as_bytes().len().saturating_sub(offset as usize),
2021-08-18 16:13:19 -07:00
Some(v) => v as usize,
};
2021-08-16 15:40:13 -07:00
Ok(DisasmIterator {
2021-08-18 16:13:19 -07:00
bytes: code.into(),
2021-08-16 15:40:13 -07:00
addr,
2021-08-18 16:13:19 -07:00
offset,
left,
2021-08-16 15:40:13 -07:00
})
}
#[pymodule]
fn ppc750cl(_: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<Ins>()?;
m.add_wrapped(wrap_pyfunction!(disasm_iter))?;
Ok(())
}