test_types.rs 8.63 KB
Newer Older
1
// Copyright 2017 The Australian National University
qinsoon's avatar
qinsoon committed
2
//
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
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
qinsoon's avatar
qinsoon committed
8
//
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
use self::mu::ast::ptr::*;
use self::mu::ast::types::*;
20
use std::sync::Arc;
21 22 23

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

102 103 104 105 106 107 108
    types
}

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

qinsoon's avatar
qinsoon committed
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>>");
117
    assert_type!(*types[7], "MyStructTag1");
118 119
    {
        let map = STRUCT_TAG_MAP.read().unwrap();
120
        let t7_struct_ty = map.get(&"MyStructTag1".to_string()).unwrap();
qinsoon's avatar
qinsoon committed
121
        assert_type!(t7_struct_ty, "struct<int<8> float>");
122
    }
qinsoon's avatar
qinsoon committed
123
    assert_type!(*types[8], "array<int<8> 5>");
124
    assert_type!(*types[9], "MyHybridTag1");
qinsoon's avatar
qinsoon committed
125 126 127 128 129
    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>");
Isaac Oscar Gariano's avatar
Isaac Oscar Gariano committed
130
    assert_type!(*types[15], "funcref<(int<8> int<8>)->(void)>");
131
    assert_type!(*types[16], "ufuncptr<(int<8> int<8>)->(void)>");
132 133 134 135 136
}

#[test]
fn test_cyclic_struct() {
    // .typedef @cyclic_struct_ty = struct<ref<@cyclic_struct_ty> int<32>>
qinsoon's avatar
qinsoon committed
137 138
    let ty = P(MuType::new(
        0,
139
        MuType_::mustruct_empty(Arc::new("MyStructTag2".to_string())),
qinsoon's avatar
qinsoon committed
140
    ));
141 142
    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
143

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

153
    let map = STRUCT_TAG_MAP.read().unwrap();
154
    let struct_ty = map.get(&"MyStructTag2".to_string()).unwrap();
155
    assert_type!(struct_ty, "struct<ref<MyStructTag2> int<32>>");
156 157 158 159 160
}

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

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

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

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