use raw::*;
use function::Func;
use types::Ty;
use util::{from_ptr, from_ptr_opt};
use value::Val;
use std::{ffi, fmt, mem, str};
use std::marker::PhantomData;
#[derive(Clone, Copy)]
pub struct Instruction<'a> {
_insn: jit_insn_t,
marker: PhantomData<&'a ()>
}
native_ref!(contra Instruction, _insn: jit_insn_t);
impl<'a> Instruction<'a> {
pub fn get_opcode(self) -> i32 {
unsafe {
jit_insn_get_opcode(self._insn)
}
}
pub fn get_dest(self) -> Option<&'a Val> {
unsafe {
from_ptr_opt(jit_insn_get_dest(self._insn))
}
}
pub fn dest_is_value(self) -> bool {
unsafe {
jit_insn_dest_is_value(self._insn) != 0
}
}
pub fn get_value1(self) -> Option<&'a Val> {
unsafe {
from_ptr_opt(jit_insn_get_value1(self._insn))
}
}
pub fn get_value2(self) -> Option<&'a Val> {
unsafe {
from_ptr_opt(jit_insn_get_value2(self._insn))
}
}
pub fn get_function(self) -> Option<&'a Func> {
unsafe {
from_ptr_opt(jit_insn_get_function(self._insn))
}
}
pub fn get_signature(self) -> Option<&'a Ty> {
unsafe {
from_ptr_opt(jit_insn_get_signature(self._insn))
}
}
pub fn get_name(self) -> &'a str {
unsafe {
let c_name = jit_insn_get_name(self._insn);
let c_name = ffi::CStr::from_ptr(c_name);
str::from_utf8(c_name.to_bytes()).unwrap()
}
}
}
impl<'a> fmt::Display for Instruction<'a> {
fn fmt(&self, fmt:&mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}", self.get_name())
}
}
pub struct InstructionIter<'a> {
_iter: jit_insn_iter_t,
marker: PhantomData<&'a ()>,
}
impl<'a> Iterator for InstructionIter<'a> {
type Item = Instruction<'a>;
fn next(&mut self) -> Option<Instruction<'a>> {
unsafe {
let ptr = jit_insn_iter_next(&mut self._iter);
if ptr.is_null() {
None
} else {
Some(from_ptr(ptr))
}
}
}
}
#[derive(Clone, Copy)]
pub struct Block<'a> {
_block: jit_block_t,
marker: PhantomData<&'a ()>
}
native_ref!(contra Block, _block: jit_block_t);
impl<'a> Block<'a> {
pub fn get_function(self) -> &'a Func {
unsafe {
from_ptr(jit_block_get_function(self._block))
}
}
pub fn is_reachable(self) -> bool {
unsafe {
jit_block_is_reachable(self._block) != 0
}
}
pub fn ends_in_dead(self) -> bool {
unsafe {
jit_block_ends_in_dead(self._block) != 0
}
}
pub fn iter(self) -> InstructionIter<'a> {
unsafe {
let mut iter = mem::zeroed();
jit_insn_iter_init(&mut iter, self._block);
assert!(iter.block == self._block);
assert!(iter.posn == 0);
InstructionIter {
_iter: iter,
marker: PhantomData
}
}
}
}