test_types.rs 8.42 KB
Newer Older
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
1
// Copyright 2017 The Australian National University
qinsoon's avatar
qinsoon committed
2
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
3 4 5
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
qinsoon's avatar
qinsoon committed
6
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
7
//     http://www.apache.org/licenses/LICENSE-2.0
qinsoon's avatar
qinsoon committed
8
//
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
9 10 11 12 13 14
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

15 16
extern crate mu;

17
use self::mu::ast::ir::MuEntityHeader;
18 19 20 21 22
use self::mu::ast::ptr::*;
use self::mu::ast::types::*;

macro_rules! assert_type (
    ($test:expr, $expect: expr) => (
23
        assert_eq!(format!("{}", $test), $expect)
24 25 26
    )
);

qinsoon's avatar
qinsoon committed
27 28
/// create one of each MuType
fn create_types() -> Vec<P<MuType>> {
29
    let mut types = vec![];
qinsoon's avatar
qinsoon committed
30

31
    let t0 = MuType::new(0, MuType_::int(8));
32
    types.push(P(t0));
qinsoon's avatar
qinsoon committed
33

34
    let t1 = MuType::new(1, MuType_::float());
35
    types.push(P(t1));
qinsoon's avatar
qinsoon committed
36

37
    let t2 = MuType::new(2, MuType_::double());
38
    types.push(P(t2));
qinsoon's avatar
qinsoon committed
39

40
    let t3 = MuType::new(3, MuType_::muref(types[0].clone()));
41
    types.push(P(t3));
qinsoon's avatar
qinsoon committed
42

43
    let t4 = MuType::new(4, MuType_::iref(types[0].clone()));
44
    types.push(P(t4));
qinsoon's avatar
qinsoon committed
45

46
    let t5 = MuType::new(5, MuType_::weakref(types[0].clone()));
47
    types.push(P(t5));
qinsoon's avatar
qinsoon committed
48

49
    let t6 = MuType::new(6, MuType_::uptr(types[0].clone()));
50
    types.push(P(t6));
qinsoon's avatar
qinsoon committed
51 52 53 54 55

    let t7 = MuType::new(
        7,
        MuType_::mustruct(
            "MyStructTag1".to_string(),
56 57
            vec![types[0].clone(), types[1].clone()]
        )
qinsoon's avatar
qinsoon committed
58
    );
59
    types.push(P(t7));
qinsoon's avatar
qinsoon committed
60

61
    let t8 = MuType::new(8, MuType_::array(types[0].clone(), 5));
62
    types.push(P(t8));
qinsoon's avatar
qinsoon committed
63 64 65 66 67 68

    let t9 = MuType::new(
        9,
        MuType_::hybrid(
            "MyHybridTag1".to_string(),
            vec![types[7].clone(), types[1].clone()],
69 70
            types[0].clone()
        )
qinsoon's avatar
qinsoon committed
71
    );
72
    types.push(P(t9));
qinsoon's avatar
qinsoon committed
73

74
    let t10 = MuType::new(10, MuType_::void());
75
    types.push(P(t10));
qinsoon's avatar
qinsoon committed
76

77
    let t11 = MuType::new(11, MuType_::threadref());
78
    types.push(P(t11));
qinsoon's avatar
qinsoon committed
79

80
    let t12 = MuType::new(12, MuType_::stackref());
81
    types.push(P(t12));
qinsoon's avatar
qinsoon committed
82

83
    let t13 = MuType::new(13, MuType_::tagref64());
84
    types.push(P(t13));
qinsoon's avatar
qinsoon committed
85

86
    let t14 = MuType::new(14, MuType_::vector(types[0].clone(), 5));
87
    types.push(P(t14));
qinsoon's avatar
qinsoon committed
88 89 90 91

    let sig = P(MuFuncSig {
        hdr: MuEntityHeader::unnamed(20),
        ret_tys: vec![types[10].clone()],
92
        arg_tys: vec![types[0].clone(), types[0].clone()]
qinsoon's avatar
qinsoon committed
93 94
    });

95
    let t15 = MuType::new(15, MuType_::funcref(sig.clone()));
96
    types.push(P(t15));
qinsoon's avatar
qinsoon committed
97

98
    let t16 = MuType::new(16, MuType_::ufuncptr(sig.clone()));
99
    types.push(P(t16));
qinsoon's avatar
qinsoon committed
100

101 102 103 104 105 106 107
    types
}

#[test]
#[allow(unused_variables)]
fn test_type_constructors() {
    let types = create_types();
qinsoon's avatar
qinsoon committed
108

qinsoon's avatar
qinsoon committed
109 110 111 112 113 114 115 116
    assert_type!(*types[0], "int<8>");
    assert_type!(*types[1], "float");
    assert_type!(*types[2], "double");
    assert_type!(*types[3], "ref<int<8>>");
    assert_type!(*types[4], "iref<int<8>>");
    assert_type!(*types[5], "weakref<int<8>>");
    assert_type!(*types[6], "uptr<int<8>>");
    assert_type!(*types[7], "MyStructTag1(struct)");
117 118 119
    {
        let map = STRUCT_TAG_MAP.read().unwrap();
        let t7_struct_ty = map.get("MyStructTag1").unwrap();
qinsoon's avatar
qinsoon committed
120
        assert_type!(t7_struct_ty, "struct<int<8> float>");
121
    }
qinsoon's avatar
qinsoon committed
122
    assert_type!(*types[8], "array<int<8> 5>");
123
    assert_type!(*types[9], "MyHybridTag1(hybrid)");
qinsoon's avatar
qinsoon committed
124 125 126 127 128
    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<int<8> 5>");
qinsoon's avatar
qinsoon committed
129 130
    assert_type!(*types[15], "funcref<[int<8>, int<8>] -> [void]>");
    assert_type!(*types[16], "ufuncref<[int<8>, int<8>] -> [void]>");
131 132 133 134 135
}

#[test]
fn test_cyclic_struct() {
    // .typedef @cyclic_struct_ty = struct<ref<@cyclic_struct_ty> int<32>>
qinsoon's avatar
qinsoon committed
136 137
    let ty = P(MuType::new(
        0,
138
        MuType_::mustruct_empty("MyStructTag2".to_string())
qinsoon's avatar
qinsoon committed
139
    ));
140 141
    let ref_ty = P(MuType::new(1, MuType_::muref(ty.clone())));
    let i32_ty = P(MuType::new(2, MuType_::int(32)));
qinsoon's avatar
qinsoon committed
142

143
    {
qinsoon's avatar
qinsoon committed
144 145 146 147 148 149
        STRUCT_TAG_MAP
            .write()
            .unwrap()
            .get_mut("MyStructTag2")
            .unwrap()
            .set_tys(vec![ref_ty.clone(), i32_ty.clone()]);
150
    }
qinsoon's avatar
qinsoon committed
151

152 153
    let map = STRUCT_TAG_MAP.read().unwrap();
    let struct_ty = map.get("MyStructTag2").unwrap();
qinsoon's avatar
qinsoon committed
154
    assert_type!(struct_ty, "struct<ref<MyStructTag2(struct)> int<32>>");
155 156 157 158 159
}

#[test]
fn test_is_traced() {
    let types = create_types();
qinsoon's avatar
qinsoon committed
160

161 162 163 164 165 166 167 168
    assert_eq!(types[0].is_traced(), false);
    assert_eq!(types[1].is_traced(), false);
    assert_eq!(types[2].is_traced(), false);
    assert_eq!(types[3].is_traced(), true);
    assert_eq!(types[4].is_traced(), true);
    assert_eq!(types[5].is_traced(), true);
    assert_eq!(types[6].is_traced(), false);
    assert_eq!(types[7].is_traced(), false);
qinsoon's avatar
qinsoon committed
169 170 171 172
    let struct3 = MuType::new(
        100,
        MuType_::mustruct(
            "MyStructTag3".to_string(),
173 174
            vec![types[3].clone(), types[0].clone()]
        )
qinsoon's avatar
qinsoon committed
175
    );
176
    assert_eq!(struct3.is_traced(), true);
qinsoon's avatar
qinsoon committed
177 178 179 180
    let struct4 = MuType::new(
        101,
        MuType_::mustruct(
            "MyStructTag4".to_string(),
181 182
            vec![types[3].clone(), types[4].clone()]
        )
qinsoon's avatar
qinsoon committed
183
    );
184 185
    assert_eq!(struct4.is_traced(), true);
    assert_eq!(types[8].is_traced(), false);
186
    let ref_array = MuType::new(102, MuType_::array(types[3].clone(), 5));
187 188
    assert_eq!(ref_array.is_traced(), true);
    assert_eq!(types[9].is_traced(), false);
qinsoon's avatar
qinsoon committed
189 190 191 192 193
    let fix_ref_hybrid = MuType::new(
        103,
        MuType_::hybrid(
            "FixRefHybrid".to_string(),
            vec![types[3].clone(), types[0].clone()],
194 195
            types[0].clone()
        )
qinsoon's avatar
qinsoon committed
196
    );
197
    assert_eq!(fix_ref_hybrid.is_traced(), true);
qinsoon's avatar
qinsoon committed
198 199 200 201 202
    let var_ref_hybrid = MuType::new(
        104,
        MuType_::hybrid(
            "VarRefHybrid".to_string(),
            vec![types[0].clone(), types[1].clone()],
203 204
            types[3].clone()
        )
qinsoon's avatar
qinsoon committed
205
    );
206 207 208 209 210 211 212 213
    assert_eq!(var_ref_hybrid.is_traced(), true);
    assert_eq!(types[10].is_traced(), false);
    assert_eq!(types[11].is_traced(), true);
    assert_eq!(types[12].is_traced(), true);
    assert_eq!(types[13].is_traced(), true);
    assert_eq!(types[14].is_traced(), false);
    assert_eq!(types[15].is_traced(), false);
    assert_eq!(types[16].is_traced(), false);
214 215 216 217
}

#[test]
fn test_is_native_safe() {
qinsoon's avatar
qinsoon committed
218 219
    let types = create_types();

220 221 222 223 224 225 226 227
    assert_eq!(types[0].is_native_safe(), true);
    assert_eq!(types[1].is_native_safe(), true);
    assert_eq!(types[2].is_native_safe(), true);
    assert_eq!(types[3].is_native_safe(), false);
    assert_eq!(types[4].is_native_safe(), false);
    assert_eq!(types[5].is_native_safe(), false);
    assert_eq!(types[6].is_native_safe(), true);
    assert_eq!(types[7].is_native_safe(), true);
qinsoon's avatar
qinsoon committed
228 229 230 231
    let struct3 = MuType::new(
        100,
        MuType_::mustruct(
            "MyStructTag3".to_string(),
232 233
            vec![types[3].clone(), types[0].clone()]
        )
qinsoon's avatar
qinsoon committed
234
    );
235
    assert_eq!(struct3.is_native_safe(), false);
qinsoon's avatar
qinsoon committed
236 237 238 239
    let struct4 = MuType::new(
        101,
        MuType_::mustruct(
            "MyStructTag4".to_string(),
240 241
            vec![types[3].clone(), types[4].clone()]
        )
qinsoon's avatar
qinsoon committed
242
    );
243 244
    assert_eq!(struct4.is_native_safe(), false);
    assert_eq!(types[8].is_native_safe(), true);
245
    let ref_array = MuType::new(102, MuType_::array(types[3].clone(), 5));
246 247
    assert_eq!(ref_array.is_native_safe(), false);
    assert_eq!(types[9].is_native_safe(), true);
qinsoon's avatar
qinsoon committed
248 249 250 251 252
    let fix_ref_hybrid = MuType::new(
        103,
        MuType_::hybrid(
            "FixRefHybrid".to_string(),
            vec![types[3].clone(), types[0].clone()],
253 254
            types[0].clone()
        )
qinsoon's avatar
qinsoon committed
255
    );
256
    assert_eq!(fix_ref_hybrid.is_native_safe(), false);
qinsoon's avatar
qinsoon committed
257 258 259 260 261
    let var_ref_hybrid = MuType::new(
        104,
        MuType_::hybrid(
            "VarRefHybrid".to_string(),
            vec![types[0].clone(), types[1].clone()],
262 263
            types[3].clone()
        )
qinsoon's avatar
qinsoon committed
264
    );
265 266 267 268 269 270
    assert_eq!(var_ref_hybrid.is_native_safe(), false);
    assert_eq!(types[10].is_native_safe(), true);
    assert_eq!(types[11].is_native_safe(), false);
    assert_eq!(types[12].is_native_safe(), false);
    assert_eq!(types[13].is_native_safe(), false);
    assert_eq!(types[14].is_native_safe(), true);
qinsoon's avatar
qinsoon committed
271 272
    assert_eq!(types[15].is_native_safe(), false); // funcref is not native safe
    // and not traced either
273
    assert_eq!(types[16].is_native_safe(), true);
274
}