extern crate mu;
use self::mu::ast::ptr::*;
use self::mu::ast::types::*;
macro_rules! assert_type (
($test:expr, $expect: expr) => (
assert_eq!(format!("{}", $test), $expect)
)
);
macro_rules! println_type (
($test:expr) => (
println!("{}", $test)
)
);
/// create one of each MuType
fn create_types() -> Vec
> {
let mut types = vec![];
let t0 = MuType::new(0, MuType_::int(8));
types.push(P(t0));
let t1 = MuType::new(1, MuType_::float());
types.push(P(t1));
let t2 = MuType::new(2, MuType_::double());
types.push(P(t2));
let t3 = MuType::new(3, MuType_::muref(types[0].clone()));
types.push(P(t3));
let t4 = MuType::new(4, MuType_::iref(types[0].clone()));
types.push(P(t4));
let t5 = MuType::new(5, MuType_::weakref(types[0].clone()));
types.push(P(t5));
let t6 = MuType::new(6, MuType_::uptr(types[0].clone()));
types.push(P(t6));
let t7 = MuType::new(7, MuType_::mustruct("MyStructTag1", vec![types[0].clone(), types[1].clone()]));
types.push(P(t7));
let t8 = MuType::new(8, MuType_::array(types[0].clone(), 5));
types.push(P(t8));
let t9 = MuType::new(9, MuType_::hybrid(vec![types[7].clone(), types[1].clone()], types[0].clone()));
types.push(P(t9));
let t10 = MuType::new(10, MuType_::void());
types.push(P(t10));
let t11 = MuType::new(11, MuType_::threadref());
types.push(P(t11));
let t12 = MuType::new(12, MuType_::stackref());
types.push(P(t12));
let t13 = MuType::new(13, MuType_::tagref64());
types.push(P(t13));
let t14 = MuType::new(14, MuType_::vector(types[0].clone(), 5));
types.push(P(t14));
let sig = P(MuFuncSig{ret_tys: vec![types[10].clone()], arg_tys: vec![types[0].clone(), types[0].clone()]});
let t15 = MuType::new(15, MuType_::funcref(sig.clone()));
types.push(P(t15));
let t16 = MuType::new(16, MuType_::ufuncptr(sig.clone()));
types.push(P(t16));
types
}
#[test]
#[allow(unused_variables)]
fn test_type_constructors() {
let types = create_types();
assert_type!(*types[0], "int<8>");
assert_type!(*types[1], "float");
assert_type!(*types[2], "double");
assert_type!(*types[3], "ref>");
assert_type!(*types[4], "iref>");
assert_type!(*types[5], "weakref>");
assert_type!(*types[6], "uptr>");
assert_type!(*types[7], "MyStructTag1(struct)");
{
let map = STRUCT_TAG_MAP.read().unwrap();
let t7_struct_ty = map.get("MyStructTag1").unwrap();
assert_type!(t7_struct_ty, "struct float>");
}
assert_type!(*types[8], "array 5>");
assert_type!(*types[9], "hybrid<[MyStructTag1(struct), float] int<8>>");
assert_type!(*types[10], "void");
assert_type!(*types[11], "threadref");
assert_type!(*types[12], "stackref");
assert_type!(*types[13], "tagref64");
assert_type!(*types[14], "vector 5>");
assert_type!(*types[15], "funcref<[void] -> [int<8>, int<8>]>");
assert_type!(*types[16], "ufuncref<[void] -> [int<8>, int<8>]>");
}
#[test]
fn test_cyclic_struct() {
// .typedef @cyclic_struct_ty = struct[ int<32>>
let ty = P(MuType::new(0, MuType_::mustruct_empty("MyStructTag2")));
let ref_ty = P(MuType::new(1, MuType_::muref(ty.clone())));
let i32_ty = P(MuType::new(2, MuType_::int(32)));
{
STRUCT_TAG_MAP.write().unwrap().
get_mut("MyStructTag2").unwrap().set_tys(vec![ref_ty.clone(), i32_ty.clone()]);
}
let map = STRUCT_TAG_MAP.read().unwrap();
let struct_ty = map.get("MyStructTag2").unwrap();
assert_type!(struct_ty, "struct][ int<32>>");
}
#[test]
fn test_is_traced() {
let types = create_types();
assert_eq!(is_traced(&types[0]), false);
assert_eq!(is_traced(&types[1]), false);
assert_eq!(is_traced(&types[2]), false);
assert_eq!(is_traced(&types[3]), true);
assert_eq!(is_traced(&types[4]), true);
assert_eq!(is_traced(&types[5]), true);
assert_eq!(is_traced(&types[6]), false);
assert_eq!(is_traced(&types[7]), false);
let struct3 = MuType::new(100, MuType_::mustruct("MyStructTag3", vec![types[3].clone(), types[0].clone()]));
assert_eq!(is_traced(&struct3), true);
let struct4 = MuType::new(101, MuType_::mustruct("MyStructTag4", vec![types[3].clone(), types[4].clone()]));
assert_eq!(is_traced(&struct4), true);
assert_eq!(is_traced(&types[8]), false);
let ref_array = MuType::new(102, MuType_::array(types[3].clone(), 5));
assert_eq!(is_traced(&ref_array), true);
assert_eq!(is_traced(&types[9]), false);
let fix_ref_hybrid = MuType::new(103, MuType_::hybrid(vec![types[3].clone(), types[0].clone()], types[0].clone()));
assert_eq!(is_traced(&fix_ref_hybrid), true);
let var_ref_hybrid = MuType::new(104, MuType_::hybrid(vec![types[0].clone(), types[1].clone()], types[3].clone()));
assert_eq!(is_traced(&var_ref_hybrid), true);
assert_eq!(is_traced(&types[10]), false);
assert_eq!(is_traced(&types[11]), true);
assert_eq!(is_traced(&types[12]), true);
assert_eq!(is_traced(&types[13]), true);
assert_eq!(is_traced(&types[14]), false);
assert_eq!(is_traced(&types[15]), false);
assert_eq!(is_traced(&types[16]), false);
}
#[test]
fn test_is_native_safe() {
let types = create_types();
assert_eq!(is_native_safe(&types[0]), true);
assert_eq!(is_native_safe(&types[1]), true);
assert_eq!(is_native_safe(&types[2]), true);
assert_eq!(is_native_safe(&types[3]), false);
assert_eq!(is_native_safe(&types[4]), false);
assert_eq!(is_native_safe(&types[5]), false);
assert_eq!(is_native_safe(&types[6]), true);
assert_eq!(is_native_safe(&types[7]), true);
let struct3 = MuType::new(100, MuType_::mustruct("MyStructTag3", vec![types[3].clone(), types[0].clone()]));
assert_eq!(is_native_safe(&struct3), false);
let struct4 = MuType::new(101, MuType_::mustruct("MyStructTag4", vec![types[3].clone(), types[4].clone()]));
assert_eq!(is_native_safe(&struct4), false);
assert_eq!(is_native_safe(&types[8]), true);
let ref_array = MuType::new(102, MuType_::array(types[3].clone(), 5));
assert_eq!(is_native_safe(&ref_array), false);
assert_eq!(is_native_safe(&types[9]), true);
let fix_ref_hybrid = MuType::new(103, MuType_::hybrid(vec![types[3].clone(), types[0].clone()], types[0].clone()));
assert_eq!(is_native_safe(&fix_ref_hybrid), false);
let var_ref_hybrid = MuType::new(104, MuType_::hybrid(vec![types[0].clone(), types[1].clone()], types[3].clone()));
assert_eq!(is_native_safe(&var_ref_hybrid), false);
assert_eq!(is_native_safe(&types[10]), true);
assert_eq!(is_native_safe(&types[11]), false);
assert_eq!(is_native_safe(&types[12]), false);
assert_eq!(is_native_safe(&types[13]), false);
assert_eq!(is_native_safe(&types[14]), true);
assert_eq!(is_native_safe(&types[15]), false); // funcref is not native safe
// and not traced either
assert_eq!(is_native_safe(&types[16]), true);
}
]