WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

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

context.rs 6.78 KB
Newer Older
qinsoon's avatar
qinsoon committed
1
2
extern crate immix_rust as gc;

qinsoon's avatar
qinsoon committed
3
4
5
6
7
use std::collections::HashMap;

use ast::ptr::P;
use ast::ir::*;
use ast::types::*;
qinsoon's avatar
qinsoon committed
8
9
use compiler::backend;
use compiler::backend::BackendTypeInfo;
10
use vm::machine_code::CompiledFunction;
qinsoon's avatar
qinsoon committed
11
use vm::vm_options::VMOptions;
qinsoon's avatar
qinsoon committed
12
use vm::api::*;
qinsoon's avatar
qinsoon committed
13

qinsoon's avatar
qinsoon committed
14
use std::sync::RwLock;
15
use std::cell::RefCell;
16
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering};
17

qinsoon's avatar
qinsoon committed
18
pub struct VM {
19
    next_id: AtomicUsize,
qinsoon's avatar
qinsoon committed
20
    is_running: AtomicBool,
21
    
qinsoon's avatar
qinsoon committed
22
23
    id_name_map: RwLock<HashMap<MuID, MuName>>,
    name_id_map: RwLock<HashMap<MuName, MuID>>,
qinsoon's avatar
qinsoon committed
24
    
qinsoon's avatar
qinsoon committed
25
26
    constants: RwLock<HashMap<MuName, P<Value>>>,
    
qinsoon's avatar
qinsoon committed
27
    types: RwLock<HashMap<MuID, P<MuType>>>,
qinsoon's avatar
qinsoon committed
28
    backend_type_info: RwLock<HashMap<P<MuType>, BackendTypeInfo>>,
29
    
qinsoon's avatar
qinsoon committed
30
    globals: RwLock<HashMap<MuName, P<GlobalCell>>>,
qinsoon's avatar
qinsoon committed
31
    
qinsoon's avatar
qinsoon committed
32
    func_sigs: RwLock<HashMap<MuName, P<MuFuncSig>>>,
qinsoon's avatar
qinsoon committed
33
34
    func_vers: RwLock<HashMap<(MuID, MuID), RefCell<MuFunctionVersion>>>,
    funcs: RwLock<HashMap<MuID, RefCell<MuFunction>>>,
qinsoon's avatar
qinsoon committed
35
    
qinsoon's avatar
qinsoon committed
36
    compiled_funcs: RwLock<HashMap<MuID, RefCell<CompiledFunction>>>
qinsoon's avatar
qinsoon committed
37
38
}

qinsoon's avatar
qinsoon committed
39
40
41
impl <'a> VM {
    pub fn new() -> VM {
        let ret = VM {
42
            next_id: ATOMIC_USIZE_INIT,
43
44
            is_running: ATOMIC_BOOL_INIT,
            
qinsoon's avatar
qinsoon committed
45
46
47
            id_name_map: RwLock::new(HashMap::new()),
            name_id_map: RwLock::new(HashMap::new()),
            
qinsoon's avatar
qinsoon committed
48
            constants: RwLock::new(HashMap::new()),
qinsoon's avatar
qinsoon committed
49
            
qinsoon's avatar
qinsoon committed
50
            types: RwLock::new(HashMap::new()),
qinsoon's avatar
qinsoon committed
51
            backend_type_info: RwLock::new(HashMap::new()),
52
            
qinsoon's avatar
qinsoon committed
53
54
55
            globals: RwLock::new(HashMap::new()),
            
            func_sigs: RwLock::new(HashMap::new()),
56
            func_vers: RwLock::new(HashMap::new()),
qinsoon's avatar
qinsoon committed
57
58
            funcs: RwLock::new(HashMap::new()),
            compiled_funcs: RwLock::new(HashMap::new())
59
60
61
        };
        
        ret.is_running.store(false, Ordering::SeqCst);
qinsoon's avatar
qinsoon committed
62
        ret.next_id.store(USER_ID_START, Ordering::SeqCst);
63
        
qinsoon's avatar
qinsoon committed
64
65
66
        let options = VMOptions::default();
        gc::gc_init(options.immix_size, options.lo_size, options.n_gcthreads);
        
67
68
69
        ret
    }
    
70
71
72
73
    pub fn next_id(&self) -> MuID {
        self.next_id.fetch_add(1, Ordering::SeqCst)
    }
    
74
75
76
77
78
79
    pub fn run_vm(&self) {
        self.is_running.store(true, Ordering::SeqCst);
    }
    
    pub fn is_running(&self) -> bool {
        self.is_running.load(Ordering::Relaxed)
qinsoon's avatar
qinsoon committed
80
81
    }
    
qinsoon's avatar
qinsoon committed
82
    pub fn declare_const(&self, id: MuID, const_name: MuName, ty: P<MuType>, val: Constant) -> P<Value> {
qinsoon's avatar
qinsoon committed
83
84
        let mut constants = self.constants.write().unwrap();
        debug_assert!(!constants.contains_key(const_name));
qinsoon's avatar
qinsoon committed
85
        
qinsoon's avatar
qinsoon committed
86
        let ret = P(Value{id: id, name: Some(const_name), ty: ty, v: Value_::Constant(val)});
qinsoon's avatar
qinsoon committed
87
        constants.insert(const_name, ret.clone());
qinsoon's avatar
qinsoon committed
88
89
90
91
        
        ret
    }
    
qinsoon's avatar
qinsoon committed
92
    pub fn declare_global(&self, id: MuID, global_name: MuName, ty: P<MuType>) -> P<Value> {
qinsoon's avatar
qinsoon committed
93
94
95
96
97
98
        let global = P(GlobalCell{tag: global_name, ty: ty.clone()});
        
        let mut globals = self.globals.write().unwrap();
        globals.insert(global_name, global.clone());
        
        P(Value{
qinsoon's avatar
qinsoon committed
99
100
            id: id,
            name: Some(global_name),
qinsoon's avatar
qinsoon committed
101
            ty: P(MuType::new(self.next_id(), MuType_::iref(ty))),
qinsoon's avatar
qinsoon committed
102
103
104
105
            v: Value_::Global(global.clone())
        })
    }
    
qinsoon's avatar
qinsoon committed
106
107
108
    pub fn declare_type(&self, id: MuID, ty: MuType_) -> P<MuType> {
        let ty = P(MuType{id: id, name: None, v: ty});
        
qinsoon's avatar
qinsoon committed
109
        let mut types = self.types.write().unwrap();
qinsoon's avatar
qinsoon committed
110
        debug_assert!(!types.contains_key(&id));
qinsoon's avatar
qinsoon committed
111
        
qinsoon's avatar
qinsoon committed
112
        types.insert(ty.id(), ty.clone());
qinsoon's avatar
qinsoon committed
113
114
115
116
        
        ty
    }
    
qinsoon's avatar
qinsoon committed
117
    pub fn declare_func_sig(&self, sig_name: MuName, ret_tys: Vec<P<MuType>>, arg_tys: Vec<P<MuType>>) -> P<MuFuncSig> {
qinsoon's avatar
qinsoon committed
118
        let mut func_sigs = self.func_sigs.write().unwrap();
qinsoon's avatar
qinsoon committed
119
        debug_assert!(!func_sigs.contains_key(&sig_name));
qinsoon's avatar
qinsoon committed
120
121
        
        let ret = P(MuFuncSig{ret_tys: ret_tys, arg_tys: arg_tys});
qinsoon's avatar
qinsoon committed
122
        func_sigs.insert(sig_name, ret.clone());
qinsoon's avatar
qinsoon committed
123
124
125
126
        
        ret
    }
    
127
    pub fn declare_func (&self, func: MuFunction) {
qinsoon's avatar
qinsoon committed
128
        info!("declare function {:?}", func);
qinsoon's avatar
qinsoon committed
129
        let mut funcs = self.funcs.write().unwrap();
qinsoon's avatar
qinsoon committed
130
        funcs.insert(func.id, RefCell::new(func));
131
132
    }
    
133
    pub fn define_func_version (&self, func_ver: MuFunctionVersion) {
qinsoon's avatar
qinsoon committed
134
        info!("define function {} with version {}", func_ver.func_id, func_ver.id);
135
        // record this version
qinsoon's avatar
qinsoon committed
136
        let func_ver_key = (func_ver.func_id, func_ver.id);
137
138
139
140
141
142
143
144
145
146
147
        {
            let mut func_vers = self.func_vers.write().unwrap();
            func_vers.insert(func_ver_key, RefCell::new(func_ver));
        }
        
        // acquire a reference to the func_ver
        let func_vers = self.func_vers.read().unwrap();
        let func_ver = func_vers.get(&func_ver_key).unwrap().borrow();
        
        // change current version to this (obsolete old versions)
        let funcs = self.funcs.read().unwrap();
qinsoon's avatar
qinsoon committed
148
149
        debug_assert!(funcs.contains_key(&func_ver.func_id)); // it should be declared before defining
        let mut func = funcs.get(&func_ver.func_id).unwrap().borrow_mut();
150
151
152
153
154
155
156
157
        
        if func.cur_ver.is_some() {
            let obsolete_ver = func.cur_ver.unwrap();
            func.all_vers.push(obsolete_ver);
            
            // redefinition happens here
            // do stuff
        }
qinsoon's avatar
qinsoon committed
158
        func.cur_ver = Some(func_ver.id);        
159
160
    }
    
161
    pub fn add_compiled_func (&self, func: CompiledFunction) {
qinsoon's avatar
qinsoon committed
162
        debug_assert!(self.funcs.read().unwrap().contains_key(&func.func_ver_id));
qinsoon's avatar
qinsoon committed
163

qinsoon's avatar
qinsoon committed
164
        self.compiled_funcs.write().unwrap().insert(func.func_ver_id, RefCell::new(func));
qinsoon's avatar
qinsoon committed
165
166
    }
    
qinsoon's avatar
qinsoon committed
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
    pub fn get_backend_type_info(&self, ty: &P<MuType>) -> BackendTypeInfo {
        {
            let read_lock = self.backend_type_info.read().unwrap();
        
            match read_lock.get(ty) {
                Some(info) => {return info.clone();},
                None => {}
            }
        }
        
        let resolved = backend::resolve_backend_type_info(ty, self);
        
        let mut write_lock = self.backend_type_info.write().unwrap();
        write_lock.insert(ty.clone(), resolved.clone());
        
        resolved        
    }
    
qinsoon's avatar
qinsoon committed
185
186
187
188
189
190
191
192
193
    pub fn get_id_of(&self, name: MuName) -> MuID {
        *self.name_id_map.read().unwrap().get(&name).unwrap()
    }
    
    pub fn get_name_of(&self, id: MuID) -> MuName {
        *self.id_name_map.read().unwrap().get(&id).unwrap()
    }
    
    pub fn globals(&self) -> &RwLock<HashMap<MuName, P<GlobalCell>>> {
qinsoon's avatar
qinsoon committed
194
195
196
        &self.globals
    }
    
qinsoon's avatar
qinsoon committed
197
    pub fn funcs(&self) -> &RwLock<HashMap<MuID, RefCell<MuFunction>>> {
qinsoon's avatar
qinsoon committed
198
        &self.funcs
199
    }
200
    
qinsoon's avatar
qinsoon committed
201
    pub fn func_vers(&self) -> &RwLock<HashMap<(MuID, MuID), RefCell<MuFunctionVersion>>> {
202
203
204
        &self.func_vers
    }
    
qinsoon's avatar
qinsoon committed
205
    pub fn compiled_funcs(&self) -> &RwLock<HashMap<MuID, RefCell<CompiledFunction>>> {
206
207
        &self.compiled_funcs
    }
208
}