96 lines
2.1 KiB
Rust
96 lines
2.1 KiB
Rust
use pyo3::prelude::*;
|
|
use pyo3::types::PyBytes;
|
|
use pyo3::{PyIterProtocol, PyObjectProtocol};
|
|
|
|
use ppc750cl::formatter::FormattedIns;
|
|
|
|
#[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()
|
|
}
|
|
}
|
|
|
|
#[pyclass]
|
|
struct DisasmIterator {
|
|
bytes: Py<PyBytes>,
|
|
addr: u32,
|
|
offset: u32,
|
|
left: usize,
|
|
}
|
|
|
|
#[pyproto]
|
|
impl PyIterProtocol for DisasmIterator {
|
|
fn __iter__(slf: PyRef<Self>) -> PyRef<DisasmIterator> {
|
|
slf
|
|
}
|
|
fn __next__(mut slf: PyRefMut<Self>) -> PyResult<Option<Ins>> {
|
|
if slf.left < 4 {
|
|
return Ok(None);
|
|
}
|
|
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);
|
|
slf.offset += 4;
|
|
slf.left -= 4;
|
|
let ins = Ins::new(code, slf.addr);
|
|
slf.addr += 4;
|
|
Ok(Some(ins))
|
|
}
|
|
}
|
|
|
|
#[pyfunction(code, addr, offset = "0", size = "None")]
|
|
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),
|
|
Some(v) => v as usize,
|
|
};
|
|
Ok(DisasmIterator {
|
|
bytes: code.into(),
|
|
addr,
|
|
offset,
|
|
left,
|
|
})
|
|
}
|
|
|
|
#[pymodule]
|
|
fn ppc750cl(_: Python, m: &PyModule) -> PyResult<()> {
|
|
m.add_class::<Ins>()?;
|
|
m.add_wrapped(wrap_pyfunction!(disasm_iter))?;
|
|
Ok(())
|
|
}
|