handle.rs 5.67 KB
Newer Older
1
use ast::ir::*;
qinsoon's avatar
qinsoon committed
2 3
use ast::ptr::*;
use ast::types::*;
4 5 6 7

use utils::BitSize;
use utils::Address;

qinsoon's avatar
qinsoon committed
8 9
use std::fmt;

10 11 12
pub type APIHandleResult = Box<APIHandle>;
pub type APIHandleArg<'a>    = &'a APIHandle;

qinsoon's avatar
qinsoon committed
13
#[derive(Clone)]
14 15 16 17 18
pub struct APIHandle {
    pub id: MuID,
    pub v: APIHandleValue
}

qinsoon's avatar
qinsoon committed
19 20 21 22 23 24 25 26 27 28 29 30 31
impl fmt::Display for APIHandle {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{:?}", self)
    }
}

impl fmt::Debug for APIHandle {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "Handle#{}=[{:?}]", self.id, self.v)
    }
}

#[derive(Clone)]
32 33 34 35
pub enum APIHandleValue {
    Int(u64, BitSize),
    Float(f32),
    Double(f64),
36 37
    UPtr(P<MuType>, Address),  // uptr<T>
    UFP (P<MuType>, Address),  // ufuncptr<sig>
38 39 40 41 42 43 44

    // SeqValue
    Struct(Vec<APIHandleValue>),
    Array (Vec<APIHandleValue>),
    Vector(Vec<APIHandleValue>),

    // GenRef
qinsoon's avatar
qinsoon committed
45 46
    Ref (P<MuType>, Address),   // referenced type
    IRef(P<MuType>, Address),
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
    TagRef64(u64),
    FuncRef,
    ThreadRef,
    StackRef,
    FCRef, // frame cursor ref

    // GenRef->IR
    Bundle,

    // GenRef->IR->Child
    Type(MuID),
    FuncSig(MuID),
    FuncVer(MuID),
    BB,
    Inst,

    // GenRef->IR->Child->Var->Global
    Global(MuID),
65
    Func(MuID),
66 67 68 69 70 71 72 73
    ExpFunc,

    // GenRef->IR->Child->Var->Local
    NorParam,
    ExcParam,
    InstRes,
}

qinsoon's avatar
qinsoon committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
impl fmt::Display for APIHandleValue {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(f, "{:?}", self)
    }
}

impl fmt::Debug for APIHandleValue {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        use self::APIHandleValue::*;
        match self {
            &Int(val, len)            => write!(f, "{} as int<{}>", val, len),
            &Float(val)               => write!(f, "{}", val),
            &Double(val)              => write!(f, "{}", val),
            &UPtr(ref ty, addr)           => write!(f, "uptr<{}> to {}", ty, addr),
            &UFP(ref sig, addr)           => write!(f, "ufp<{}> to {}", sig, addr),
            &Struct(ref vec)          => write!(f, "struct{{{:?}}}", vec),
            &Array(ref vec)           => write!(f, "array{{{:?}}}", vec),
            &Vector(ref vec)          => write!(f, "vector{{{:?}}}", vec),
            &Ref(ref ty, addr)        => write!(f, "ref<{}> to {}", ty, addr),
            &IRef(ref ty, addr)       => write!(f, "iref<{}> to {}", ty, addr),
            &TagRef64(val)            => write!(f, "tagref64 0x{:x}", val),
            &FuncRef                  => write!(f, "funcref"),
            &ThreadRef                => write!(f, "threadref"),
            &StackRef                 => write!(f, "stackref"),
            &FCRef                    => write!(f, "framecursorref"),
            &Bundle                   => write!(f, "IR.bundle"),
            &Type(id)                 => write!(f, "IR.type to #{}", id),
            &FuncSig(id)              => write!(f, "IR.funcsig to #{}", id),
            &FuncVer(id)              => write!(f, "IR.funcver to #{}", id),
            &BB                       => write!(f, "IR.BB"),
            &Inst                     => write!(f, "IR.inst"),
            &Global(id)               => write!(f, "IR.global to #{}", id),
            &Func(id)                 => write!(f, "IR.func to #{}", id),
            &ExpFunc                  => write!(f, "IR.expfunc"),
            &NorParam                 => write!(f, "IR.norparam"),
            &ExcParam                 => write!(f, "IR.excparam"),
            &InstRes                  => write!(f, "IR.instres")
        }
    }
}

115
impl APIHandleValue {
qinsoon's avatar
qinsoon committed
116 117 118 119 120 121 122 123
    pub fn as_ref_or_iref(&self) -> (P<MuType>, Address) {
        match self {
            &APIHandleValue::Ref(ref ty, addr)
            | &APIHandleValue::IRef(ref ty, addr) => (ty.clone(), addr),
            _ => panic!("expected Ref or IRef handle")
        }
    }

qinsoon's avatar
qinsoon committed
124
    pub fn as_ref(&self) -> (P<MuType>, Address) {
125
        match self {
qinsoon's avatar
qinsoon committed
126
            &APIHandleValue::Ref(ref ty, addr) => (ty.clone(), addr),
qinsoon's avatar
qinsoon committed
127
            _ => panic!("expected Ref handle")
qinsoon's avatar
qinsoon committed
128 129 130 131 132 133
        }
    }

    pub fn as_iref(&self) -> (P<MuType>, Address) {
        match self {
            &APIHandleValue::IRef(ref ty, addr) => (ty.clone(), addr),
qinsoon's avatar
qinsoon committed
134 135 136 137
            _ => panic!("expected IRef handle")
        }
    }

qinsoon's avatar
qinsoon committed
138 139 140 141 142 143 144 145 146 147
    pub fn as_address(&self) -> Address {
        match self {
            &APIHandleValue::IRef  (_, addr)
            | &APIHandleValue::Ref (_, addr)
            | &APIHandleValue::UPtr(_, addr)
            | &APIHandleValue::UFP (_, addr) => addr,
            _ => panic!("expected iref/ref/uptr/ufp which contains a pointer, found {}", self)
        }
    }

qinsoon's avatar
qinsoon committed
148 149 150 151
    pub fn as_int(&self) -> u64 {
        match self {
            &APIHandleValue::Int(val, _) => val,
            _ => panic!("expected Int handle")
152 153
        }
    }
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181

    pub fn as_float(&self) -> f32 {
        match self {
            &APIHandleValue::Float(val) => val,
            _ => panic!("expected Float handle")
        }
    }

    pub fn as_double(&self) -> f64 {
        match self {
            &APIHandleValue::Double(val) => val,
            _ => panic!("expected Double handle")
        }
    }

    pub fn as_uptr(&self) -> (P<MuType>, Address) {
        match self {
            &APIHandleValue::UPtr(ref ty, addr) => (ty.clone(), addr),
            _ => panic!("expected UPtr handle")
        }
    }

    pub fn as_ufp(&self) -> (P<MuType>, Address) {
        match self {
            &APIHandleValue::UFP(ref ty, addr) => (ty.clone(), addr),
            _ => panic!("expected UFP handle")
        }
    }
182 183 184 185 186 187 188

    pub fn as_func(&self) -> MuID {
        match self {
            &APIHandleValue::Func(id) => id,
            _ => panic!("expected FuncRef")
        }
    }
189
}