To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

test_call.rs 4.8 KB
Newer Older
qinsoon's avatar
qinsoon committed
1
2
use mu::ast::types::*;
use mu::ast::ir::*;
3
use mu::ast::ptr::*;
qinsoon's avatar
qinsoon committed
4
5
6
7
8
9
10
use mu::ast::inst::*;
use mu::vm::*;
use mu::compiler::*;

use std::sync::RwLock;
use std::sync::Arc;
use mu::testutil::aot;
11
use mu::utils::LinkedHashMap;
qinsoon's avatar
qinsoon committed
12
13
14
15
16
17
18

#[test]
fn test_ccall_exit() {
    VM::start_logging_trace();

    let vm = Arc::new(ccall_exit());

qinsoon's avatar
qinsoon committed
19
    let compiler = Compiler::new(CompilerPolicy::default(), &vm);
qinsoon's avatar
qinsoon committed
20
21
22
23
24
25
26
27
28
29
30

    let func_id = vm.id_of("ccall_exit");
    {
        let funcs = vm.funcs().read().unwrap();
        let func = funcs.get(&func_id).unwrap().read().unwrap();
        let func_vers = vm.func_vers().read().unwrap();
        let mut func_ver = func_vers.get(&func.cur_ver.unwrap()).unwrap().write().unwrap();

        compiler.compile(&mut func_ver);
    }

qinsoon's avatar
qinsoon committed
31
    vm.make_primordial_thread(func_id, true, vec![]);
qinsoon's avatar
qinsoon committed
32
33
    backend::emit_context(&vm);

qinsoon's avatar
qinsoon committed
34
    let executable = aot::link_primordial(vec!["ccall_exit".to_string()], "ccall_exit_test", &vm);
qinsoon's avatar
qinsoon committed
35
36
37
38
39
40
41
42
43
    let output = aot::execute_nocheck(executable);

    assert!(output.status.code().is_some());

    let ret_code = output.status.code().unwrap();
    println!("return code: {}", ret_code);
    assert!(ret_code == 10);
}

44
pub fn gen_ccall_exit(arg: P<TreeNode>, func_ver: &mut MuFunctionVersion, vm: &VM) -> Box<TreeNode> {
qinsoon's avatar
qinsoon committed
45
46
    // .typedef @int32 = int<32>
    let type_def_int32 = vm.declare_type(vm.next_id(), MuType_::int(32));
47
    vm.set_name(type_def_int32.as_entity(), Mu("exit_int32"));
qinsoon's avatar
qinsoon committed
48
49
50
51
52
53
54
55
56
57
58
59
60

    // .typedef @exit_sig = (@int32) -> !
    let exit_sig = vm.declare_func_sig(vm.next_id(), vec![], vec![type_def_int32.clone()]);
    vm.set_name(exit_sig.as_entity(), Mu("exit_sig"));

    // .typedef @ufp_exit = ufuncptr(@exit_sig)
    let type_def_ufp_exit = vm.declare_type(vm.next_id(), MuType_::UFuncPtr(exit_sig.clone()));
    vm.set_name(type_def_ufp_exit.as_entity(), Mu("ufp_exit"));

    // .const @exit = EXTERN SYMBOL "exit"
    let const_exit = vm.declare_const(vm.next_id(), type_def_ufp_exit.clone(), Constant::ExternSym(C("exit")));
    vm.set_name(const_exit.as_entity(), Mu("exit"));

qinsoon's avatar
qinsoon committed
61
    // exprCCALL %const_exit (%const_int32_10)
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    let const_exit_local = func_ver.new_constant(const_exit.clone());

    func_ver.new_inst(Instruction{
        hdr: MuEntityHeader::unnamed(vm.next_id()),
        value: None,
        ops: RwLock::new(vec![const_exit_local, arg]),
        v: Instruction_::ExprCCall {
            data: CallData {
                func: 0,
                args: vec![1],
                convention: CallConvention::Foreign(ForeignFFI::C)
            },
            is_abort: false
        }
    })
}

fn ccall_exit() -> VM {
    let vm = VM::new();

    // .typedef @int32 = int<32>
    let type_def_int32 = vm.declare_type(vm.next_id(), MuType_::int(32));
    vm.set_name(type_def_int32.as_entity(), Mu("int32"));

qinsoon's avatar
qinsoon committed
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
    // .const @int32_10 = 10
    let const_int32_10 = vm.declare_const(vm.next_id(), type_def_int32.clone(), Constant::Int(10));
    vm.set_name(const_int32_10.as_entity(), Mu("const_int32_10"));

    // .const @int32_0 = 0
    let const_int32_0 = vm.declare_const(vm.next_id(), type_def_int32.clone(), Constant::Int(0));
    vm.set_name(const_int32_0.as_entity(), Mu("const_int32_0"));

    // .funcsig @ccall_exit_sig = () -> !
    let ccall_exit_sig = vm.declare_func_sig(vm.next_id(), vec![], vec![]);
    vm.set_name(ccall_exit_sig.as_entity(), Mu("ccall_exit_sig"));

    // .funcdecl @ccall_exit <@ccall_exit_sig>
    let func_id = vm.next_id();
    let func = MuFunction::new(func_id, ccall_exit_sig.clone());
    vm.set_name(func.as_entity(), Mu("ccall_exit"));
    vm.declare_func(func);

    // .funcdef @ccall_exit VERSION @ccall_exit_v1 <@ccall_exit_sig>
    let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, ccall_exit_sig.clone());
    vm.set_name(func_ver.as_entity(), Mu("ccall_exit_v1"));

    // %entry():
    let mut blk_entry = Block::new(vm.next_id());
    vm.set_name(blk_entry.as_entity(), Mu("entry"));

qinsoon's avatar
qinsoon committed
112
    // exprCCALL %const_exit (%const_int32_10)
qinsoon's avatar
qinsoon committed
113
    let const_int32_10_local = func_ver.new_constant(const_int32_10.clone());
114
    let blk_entry_ccall = gen_ccall_exit(const_int32_10_local.clone(), &mut func_ver, &vm);
qinsoon's avatar
qinsoon committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

    // RET %const_int32_0
    let const_int32_0_local = func_ver.new_constant(const_int32_0.clone());

    let blk_entry_ret = func_ver.new_inst(Instruction{
        hdr: MuEntityHeader::unnamed(vm.next_id()),
        value: None,
        ops: RwLock::new(vec![const_int32_0_local]),
        v: Instruction_::Return(vec![0])
    });

    blk_entry.content = Some(BlockContent {
        args: vec![],
        exn_arg: None,
        body: vec![blk_entry_ccall, blk_entry_ret],
        keepalives: None
    });

133
134
135
    func_ver.define(FunctionContent::new(
        blk_entry.id(),
        {
136
137
138
            let mut map = LinkedHashMap::new();
            map.insert(blk_entry.id(), blk_entry);
            map
qinsoon's avatar
qinsoon committed
139
        }
140
    ));
qinsoon's avatar
qinsoon committed
141
142
143
144

    vm.define_func_version(func_ver);

    vm
145
}