muctx.rs 15.7 KB
Newer Older
1
use super::common::*;
2 3
use utils::Address;
//use std::os::raw::c_void;
4

5
pub struct MuCtx {
6
    /// ref to MuVM
7
    mvm: *const MuVM,
8 9 10 11 12

    /// Point to the C-visible CMuCtx so that `close_context` can deallocate itself.
    pub c_struct: *mut CMuCtx,
}

13 14
impl MuCtx {
    pub fn new(mvm: *const MuVM) -> Box<MuCtx> {
15 16 17 18 19 20 21 22
        Box::new(MuCtx {
            mvm: mvm,
            c_struct: ptr::null_mut(),
        })
    }

    #[inline(always)]
    fn get_mvm(&mut self) -> &MuVM {
23 24
        //self.mvm
        unsafe { & *self.mvm }
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
    }

    pub fn id_of(&mut self, name: MuName) -> MuID {
        self.get_mvm().id_of(name)
    }

    pub fn name_of(&mut self, id: MuID) -> CMuCString {
        self.get_mvm().name_of(id)
    }

    fn deallocate(&mut self) {
        let c_struct = self.c_struct;
        let ctx_ptr = self as *mut MuCtx;
        debug!("Deallocating MuCtx {:?} and CMuCtx {:?}...", ctx_ptr, c_struct);
        unsafe {
            Box::from_raw(c_struct);
            Box::from_raw(ctx_ptr);
        }
    }

    pub fn close_context(&mut self) {
        info!("Closing MuCtx...");
        self.deallocate();
    }

    pub fn load_bundle(&mut self, buf: &[c_char]) {
        panic!("The fast implementation does not support the text form.")
    }

    pub fn load_hail(&mut self, buf: &[c_char]) {
        panic!("The fast implementation does not support the text form.")
    }

58
    pub fn handle_from_sint8(&mut self, num: i8, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
59
        trace!("handle_from_sint8");
60
        prepare_handle((self.get_mvm().vm.handle_from_sint8(num, len as usize)))
61 62
    }

63
    pub fn handle_from_uint8(&mut self, num: u8, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
64
        trace!("handle_from_uint8");
65
        prepare_handle((self.get_mvm().vm.handle_from_uint8(num, len as usize)))
66 67
    }

68
    pub fn handle_from_sint16(&mut self, num: i16, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
69
        trace!("handle_from_sint16");
70
        prepare_handle((self.get_mvm().vm.handle_from_sint16(num, len as usize)))
71 72
    }

73
    pub fn handle_from_uint16(&mut self, num: u16, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
74
        trace!("handle_from_uint16");
75
        prepare_handle((self.get_mvm().vm.handle_from_uint16(num, len as usize)))
76 77
    }

78
    pub fn handle_from_sint32(&mut self, num: i32, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
79
        trace!("handle_from_sint32");
80
        prepare_handle((self.get_mvm().vm.handle_from_sint32(num, len as usize)))
81 82
    }

83
    pub fn handle_from_uint32(&mut self, num: u32, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
84
        trace!("handle_from_uint32");
85
        prepare_handle((self.get_mvm().vm.handle_from_uint32(num, len as usize)))
86 87
    }

88
    pub fn handle_from_sint64(&mut self, num: i64, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
89
        trace!("handle_from_sint64");
90
        prepare_handle((self.get_mvm().vm.handle_from_sint64(num, len as usize)))
91 92
    }

93
    pub fn handle_from_uint64(&mut self, num: u64, len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
94
        trace!("handle_from_uint64");
95
        prepare_handle((self.get_mvm().vm.handle_from_uint64(num, len as usize)))
96 97
    }

98
    pub fn handle_from_uint64s(&mut self, nums: &[u64], len: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
99
        trace!("handle_from_uint64s");
100
        panic!("Zebu doesnt implement int with length larger than 64bits")
101 102
    }

103
    pub fn handle_from_float(&mut self, num: f32) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
104
        trace!("handle_from_float");
105
        prepare_handle((self.get_mvm().vm.handle_from_float(num)))
106 107
    }

108
    pub fn handle_from_double(&mut self, num: f64) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
109
        trace!("handle_from_double");
110
        prepare_handle((self.get_mvm().vm.handle_from_double(num)))
111 112
    }

113
    pub fn handle_from_ptr(&mut self, mu_type: MuID, ptr: CMuCPtr) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
114
        trace!("handle_from_ptr: ty#{}, {:?}", mu_type, ptr);
115 116 117
        let addr = Address::from_mut_ptr(ptr);

        prepare_handle((self.get_mvm().vm.handle_from_uptr(mu_type, addr)))
118 119
    }

120
    pub fn handle_from_fp(&mut self, mu_type: MuID, fp: CMuCFP) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
121
        trace!("handle_from_fp: ty#{}, {:?}", mu_type, fp);
122 123 124
        let addr = Address::from_mut_ptr(fp);

        prepare_handle((self.get_mvm().vm.handle_from_ufp(mu_type, addr)))
125 126
    }

127
    pub fn handle_to_sint8(&mut self, opnd: &APIHandle) -> i8 {
qinsoon's avatar
qinsoon committed
128
        trace!("handle_to_sint8: {}", opnd);
129
        self.get_mvm().vm.handle_to_sint8(opnd)
130 131
    }

132
    pub fn handle_to_uint8(&mut self, opnd: &APIHandle) -> u8 {
qinsoon's avatar
qinsoon committed
133
        trace!("handle_to_uint8: {}", opnd);
134
        self.get_mvm().vm.handle_to_uint8(opnd)
135 136
    }

137
    pub fn handle_to_sint16(&mut self, opnd: &APIHandle) -> i16 {
qinsoon's avatar
qinsoon committed
138
        trace!("handle_to_sint16: {}", opnd);
139
        self.get_mvm().vm.handle_to_sint16(opnd)
140 141
    }

142
    pub fn handle_to_uint16(&mut self, opnd: &APIHandle) -> u16 {
qinsoon's avatar
qinsoon committed
143
        trace!("handle_to_uint16: {}", opnd);
144
        self.get_mvm().vm.handle_to_uint16(opnd)
145 146
    }

147
    pub fn handle_to_sint32(&mut self, opnd: &APIHandle) -> i32 {
qinsoon's avatar
qinsoon committed
148
        trace!("handle_to_sint32: {}", opnd);
149
        self.get_mvm().vm.handle_to_sint32(opnd)
150 151
    }

152
    pub fn handle_to_uint32(&mut self, opnd: &APIHandle) -> u32 {
qinsoon's avatar
qinsoon committed
153
        trace!("handle_to_uint32: {}", opnd);
154
        self.get_mvm().vm.handle_to_uint32(opnd)
155 156
    }

157
    pub fn handle_to_sint64(&mut self, opnd: &APIHandle) -> i64 {
qinsoon's avatar
qinsoon committed
158
        trace!("handle_to_sint64: {}", opnd);
159
        self.get_mvm().vm.handle_to_sint64(opnd)
160 161
    }

162
    pub fn handle_to_uint64(&mut self, opnd: &APIHandle) -> u64 {
qinsoon's avatar
qinsoon committed
163
        trace!("handle_to_uint64: {}", opnd);
164
        self.get_mvm().vm.handle_to_uint64(opnd)
165 166
    }

167
    pub fn handle_to_float(&mut self, opnd: &APIHandle) -> f32 {
qinsoon's avatar
qinsoon committed
168
        trace!("handle_to_float: {}", opnd);
169
        self.get_mvm().vm.handle_to_float(opnd)
170 171
    }

172
    pub fn handle_to_double(&mut self, opnd: &APIHandle) -> f64 {
qinsoon's avatar
qinsoon committed
173
        trace!("handle_to_double: {}", opnd);
174
        self.get_mvm().vm.handle_to_double(opnd)
175 176
    }

177
    pub fn handle_to_ptr(&mut self, opnd: &APIHandle) -> CMuCPtr {
qinsoon's avatar
qinsoon committed
178
        trace!("handle_to_ptr: {}", opnd);
179
        self.get_mvm().vm.handle_to_uptr(opnd).to_ptr_mut()
180 181
    }

182
    pub fn handle_to_fp(&mut self, opnd: &APIHandle) -> CMuCFP {
qinsoon's avatar
qinsoon committed
183
        trace!("handle_to_fp: {}", opnd);
184
        self.get_mvm().vm.handle_to_ufp(opnd).to_ptr_mut()
185 186
    }

187
    pub fn handle_from_const(&mut self, id: MuID) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
188
        trace!("handle_from_const");
189
        prepare_handle(self.get_mvm().vm.handle_from_const(id))
190 191
    }

192
    pub fn handle_from_global(&mut self, id: MuID) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
193
        trace!("handle_from_global");
194
        prepare_handle(self.get_mvm().vm.handle_from_global(id))
195 196
    }

197
    pub fn handle_from_func(&mut self, id: MuID) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
198
        trace!("handle_from_func");
199
        prepare_handle(self.get_mvm().vm.handle_from_func(id))
200 201
    }

202
    pub fn handle_from_expose(&mut self, id: MuID) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
203
        trace!("handle_from_Expose");
204 205 206
        panic!("Not implemented")
    }

207
    pub fn delete_value(&mut self, opnd: &APIHandle) {
208
        delete_handle(opnd);
209 210
    }

211
    pub fn ref_eq(&mut self, lhs: &APIHandle, rhs: &APIHandle) -> bool {
212 213 214
        panic!("Not implemented")
    }

215
    pub fn ref_ult(&mut self, lhs: &APIHandle, rhs: &APIHandle) -> bool {
216 217 218
        panic!("Not implemented")
    }

219
    pub fn extract_value(&mut self, str: &APIHandle, index: c_int) -> *const APIHandle {
220 221 222
        panic!("Not implemented")
    }

223
    pub fn insert_value(&mut self, str: &APIHandle, index: c_int, newval: &APIHandle) -> *const APIHandle {
224 225 226
        panic!("Not implemented")
    }

227
    pub fn extract_element(&mut self, str: &APIHandle, index: &APIHandle) -> *const APIHandle {
228 229 230
        panic!("Not implemented")
    }

231
    pub fn insert_element(&mut self, str: &APIHandle, index: &APIHandle, newval: &APIHandle) -> *const APIHandle {
232 233 234
        panic!("Not implemented")
    }

235
    pub fn new_fixed(&mut self, mu_type: MuID) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
236
        trace!("new_fixed: ty#{}", mu_type);
237
        prepare_handle(self.get_mvm().vm.new_fixed(mu_type))
238 239
    }

240
    pub fn new_hybrid(&mut self, mu_type: MuID, length: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
241
        trace!("new_hybrid: ty#{}, len {}", mu_type, length);
242
        prepare_handle(self.get_mvm().vm.new_hybrid(mu_type, length))
243 244
    }

245
    pub fn refcast(&mut self, opnd: &APIHandle, new_type: MuID) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
246 247
        trace!("refcast: {} to ty#{}", opnd, new_type);
        prepare_handle(self.get_mvm().vm.handle_refcast(opnd, new_type))
248 249
    }

250
    pub fn get_iref(&mut self, opnd: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
251
        trace!("get_iref: {}", opnd);
252
        prepare_handle(self.get_mvm().vm.handle_get_iref(opnd))
253 254
    }

255
    pub fn get_field_iref(&mut self, opnd: &APIHandle, field: c_int) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
256
        trace!("get_field_iref: {}, field {}", opnd, field);
257
        prepare_handle(self.get_mvm().vm.handle_get_field_iref(opnd, field as usize))
258 259
    }

260
    pub fn get_elem_iref(&mut self, opnd: &APIHandle, index: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
261
        trace!("get_elem_iref: {}, index {}", opnd, index);
qinsoon's avatar
qinsoon committed
262
        prepare_handle(self.get_mvm().vm.handle_get_elem_iref(opnd, index))
263 264
    }

265
    pub fn shift_iref(&mut self, opnd: &APIHandle, offset: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
266
        trace!("shift_iref: {}, offset {}", opnd, offset);
267
        prepare_handle(self.get_mvm().vm.handle_shift_iref(opnd, offset))
268 269
    }

270
    pub fn get_var_part_iref(&mut self, opnd: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
271
        trace!("get_var_part_iref: {}", opnd);
272
        prepare_handle(self.get_mvm().vm.handle_get_var_part_iref(opnd))
273 274
    }

275
    pub fn load(&mut self, ord: CMuMemOrd, loc: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
276
        trace!("load: {}", loc);
277
        prepare_handle(self.get_mvm().vm.handle_load(impl_memorder(ord), loc))
278 279
    }

280
    pub fn store(&mut self, ord: CMuMemOrd, loc: &APIHandle, newval: &APIHandle) {
qinsoon's avatar
qinsoon committed
281
        trace!("store: {} val {}", loc, newval);
282
        self.get_mvm().vm.handle_store(impl_memorder(ord), loc, newval);
283 284
    }

285
    pub fn cmpxchg(&mut self, ord_succ: CMuMemOrd, ord_fail: CMuMemOrd, weak: bool, loc: &APIHandle, expected: &APIHandle, desired: &APIHandle, is_succ: *mut CMuBool) -> *const APIHandle {
286 287 288
        panic!("Not implemented")
    }

289
    pub fn atomicrmw(&mut self, ord: CMuMemOrd, op: CMuAtomicRMWOptr, loc: &APIHandle, opnd: &APIHandle) -> *const APIHandle {
290 291 292 293 294 295 296
        panic!("Not implemented")
    }

    pub fn fence(&mut self, ord: CMuMemOrd) {
        panic!("Not implemented")
    }

297
    pub fn new_stack(&mut self, func: &APIHandle) -> *const APIHandle {
298 299 300
        panic!("Not implemented")
    }

301
    pub fn new_thread_nor(&mut self, stack: &APIHandle, threadlocal: Option<&APIHandle>, vals: Vec<&APIHandle>) -> *const APIHandle {
302 303 304
        panic!("Not implemented")
    }

305
    pub fn new_thread_exc(&mut self, stack: &APIHandle, threadlocal: Option<&APIHandle>, exc: &APIHandle) -> *const APIHandle {
306 307 308
        panic!("Not implemented")
    }

309
    pub fn kill_stack(&mut self, stack: &APIHandle) {
310 311 312
        panic!("Not implemented")
    }

313
    pub fn set_threadlocal(&mut self, thread: &APIHandle, threadlocal: &APIHandle) {
314 315 316
        panic!("Not implemented")
    }

317
    pub fn get_threadlocal(&mut self, thread: &APIHandle) -> *const APIHandle {
318 319 320
        panic!("Not implemented")
    }

321
    pub fn new_cursor(&mut self, stack: &APIHandle) -> *const APIHandle {
322 323 324
        panic!("Not implemented")
    }

325
    pub fn next_frame(&mut self, cursor: &APIHandle) {
326 327 328
        panic!("Not implemented")
    }

329
    pub fn copy_cursor(&mut self, cursor: &APIHandle) -> *const APIHandle {
330 331 332
        panic!("Not implemented")
    }

333
    pub fn close_cursor(&mut self, cursor: &APIHandle) {
334 335 336
        panic!("Not implemented")
    }

337
    pub fn cur_func(&mut self, cursor: &APIHandle) -> MuID {
338 339 340
        panic!("Not implemented")
    }

341
    pub fn cur_func_ver(&mut self, cursor: &APIHandle) -> MuID {
342 343 344
        panic!("Not implemented")
    }

345
    pub fn cur_inst(&mut self, cursor: &APIHandle) -> MuID {
346 347 348
        panic!("Not implemented")
    }

349
    pub fn dump_keepalives(&mut self, cursor: &APIHandle, results: *mut CMuValue) {
350 351 352
        panic!("Not implemented")
    }

353
    pub fn pop_frames_to(&mut self, cursor: &APIHandle) {
354 355 356
        panic!("Not implemented")
    }

357
    pub fn push_frame(&mut self, stack: &APIHandle, func: &APIHandle) {
358 359 360
        panic!("Not implemented")
    }

361
    pub fn tr64_is_fp(&mut self, value: &APIHandle) -> bool {
362 363 364
        panic!("Not implemented")
    }

365
    pub fn tr64_is_int(&mut self, value: &APIHandle) -> bool {
366 367 368
        panic!("Not implemented")
    }

369
    pub fn tr64_is_ref(&mut self, value: &APIHandle) -> bool {
370 371 372
        panic!("Not implemented")
    }

373
    pub fn tr64_to_fp(&mut self, value: &APIHandle) -> *const APIHandle {
374 375 376
        panic!("Not implemented")
    }

377
    pub fn tr64_to_int(&mut self, value: &APIHandle) -> *const APIHandle {
378 379 380
        panic!("Not implemented")
    }

381
    pub fn tr64_to_ref(&mut self, value: &APIHandle) -> *const APIHandle {
382 383 384
        panic!("Not implemented")
    }

385
    pub fn tr64_to_tag(&mut self, value: &APIHandle) -> *const APIHandle {
386 387 388
        panic!("Not implemented")
    }

389
    pub fn tr64_from_fp(&mut self, value: &APIHandle) -> *const APIHandle {
390 391 392
        panic!("Not implemented")
    }

393
    pub fn tr64_from_int(&mut self, value: &APIHandle) -> *const APIHandle {
394 395 396
        panic!("Not implemented")
    }

397
    pub fn tr64_from_ref(&mut self, reff: &APIHandle, tag: &APIHandle) -> *const APIHandle {
398 399 400 401 402 403 404 405 406 407 408
        panic!("Not implemented")
    }

    pub fn enable_watchpoint(&mut self, wpid: CMuWPID) {
        panic!("Not implemented")
    }

    pub fn disable_watchpoint(&mut self, wpid: CMuWPID) {
        panic!("Not implemented")
    }

409
    pub fn pin(&mut self, loc: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
410
        prepare_handle(self.get_mvm().vm.handle_pin_object(loc))
411 412
    }

413
    pub fn unpin(&mut self, loc: &APIHandle) {
qinsoon's avatar
qinsoon committed
414
        self.get_mvm().vm.handle_unpin_object(loc)
415 416
    }

417
    pub fn get_addr(&mut self, loc: &APIHandle) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
418
        prepare_handle(self.get_mvm().vm.handle_get_addr(loc))
419 420
    }

421
    pub fn expose(&mut self, func: &APIHandle, call_conv: CMuCallConv, cookie: &APIHandle) -> *const APIHandle {
422 423 424
        panic!("Not implemented")
    }

425
    pub fn unexpose(&mut self, call_conv: CMuCallConv, value: &APIHandle) {
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
        panic!("Not implemented")
    }

    pub fn new_ir_builder(&mut self) -> *mut CMuIRBuilder {
        info!("Creating MuIRBuilder...");

        let b: Box<MuIRBuilder> = MuIRBuilder::new(self.mvm);

        let b_ptr = Box::into_raw(b);

        debug!("The MuIRBuilder address: {:?}", b_ptr);

        let cb = make_new_MuIRBuilder(b_ptr as *mut c_void);

        debug!("The C-visible CMuIRBuilder struct address: {:?}", cb);

        unsafe{ (*b_ptr).c_struct = cb; }

        cb
    }

447
    pub fn make_boot_image(&mut self, whitelist: Vec<MuID>, primordial_func: Option<&APIHandle>, primordial_stack: Option<&APIHandle>, primordial_threadlocal: Option<&APIHandle>, sym_fields: Vec<&APIHandle>, sym_strings: Vec<String>, reloc_fields: Vec<&APIHandle>, reloc_strings: Vec<String>, output_file: String) {
448
        self.get_mvm().vm.make_boot_image(whitelist, primordial_func, primordial_stack, primordial_threadlocal, sym_fields, sym_strings, reloc_fields, reloc_strings, output_file);
449 450 451
    }

}
452 453

fn prepare_handle(handle: APIHandleResult) -> *const APIHandle {
qinsoon's avatar
qinsoon committed
454 455
    trace!("got handle: {:?}", handle);

456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    Box::into_raw(handle)
}

fn delete_handle(handle: APIHandleArg) {
    unsafe {Box::from_raw((handle as *const APIHandle) as *mut APIHandle);}
}

use ast::inst::MemoryOrder;
fn impl_memorder(order: CMuMemOrd) -> MemoryOrder {
    match order {
        CMU_ORD_NOT_ATOMIC => MemoryOrder::NotAtomic,
        CMU_ORD_RELAXED    => MemoryOrder::Relaxed,
        CMU_ORD_CONSUME    => MemoryOrder::Consume,
        CMU_ORD_ACQUIRE    => MemoryOrder::Acquire,
        CMU_ORD_RELEASE    => MemoryOrder::Release,
        CMU_ORD_ACQ_REL    => MemoryOrder::AcqRel,
        CMU_ORD_SEQ_CST    => MemoryOrder::SeqCst,
        _ => panic!("invalid CMuMemOrd flag: {}", order)
    }
}