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.

Commit b44d389f authored by Kunshan Wang's avatar Kunshan Wang
Browse files

IRBuilder: Reorganise dir struture.

parent f83e4dde
/*!
* This module contains the high-level implementation of the Mu API.
*
* Structs are written in idiomatic Rust code. The internal structures of these structs are
* implementation-specific. Methods are defined using `impl`.
*/
#![allow(unused_imports)] // work in progress
#![allow(unused_variables)] // stubs
#![allow(dead_code)] // stubs
mod muvm;
mod muctx;
mod muirbuilder;
pub use self::muvm::*;
pub use self::muctx::*;
pub use self::muirbuilder::*;
mod common {
pub use std::os::raw::*;
pub use std::ptr;
pub use std::slice;
pub use std::ffi::CStr;
pub use std::ffi::CString;
pub use std::collections::HashMap;
pub use std::collections::HashSet;
pub use std::sync::Mutex;
pub use std::sync::RwLock;
pub use super::muvm::*;
pub use super::muctx::*;
pub use super::muirbuilder::*;
pub use super::super::super::vm::VM;
pub use super::super::api_c::*;
pub use super::super::api_bridge::*;
pub use super::super::irnodes::*;
pub use ast::bundle::*;
pub use ast::ir::*;
pub use ast::ptr::*;
pub use ast::types::*;
}
use super::common::*;
pub struct MuCtx<'v> {
/// ref to MuVM
mvm: &'v MuVM,
/// Point to the C-visible CMuCtx so that `close_context` can deallocate itself.
pub c_struct: *mut CMuCtx,
}
impl<'v> MuCtx<'v> {
pub fn new(mvm: &'v MuVM) -> Box<MuCtx> {
Box::new(MuCtx {
mvm: mvm,
c_struct: ptr::null_mut(),
})
}
#[inline(always)]
fn get_mvm(&mut self) -> &MuVM {
self.mvm
//unsafe { &mut *self.mvm }
}
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.")
}
pub fn handle_from_sint8(&mut self, num: i8, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_uint8(&mut self, num: u8, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_sint16(&mut self, num: i16, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_uint16(&mut self, num: u16, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_sint32(&mut self, num: i32, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_uint32(&mut self, num: u32, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_sint64(&mut self, num: i64, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_uint64(&mut self, num: u64, len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_uint64s(&mut self, nums: &[u64], len: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_float(&mut self, num: f32) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_double(&mut self, num: f64) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_ptr(&mut self, mu_type: MuID, ptr: CMuCPtr) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_fp(&mut self, mu_type: MuID, fp: CMuCFP) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_to_sint8(&mut self, opnd: &APIMuValue) -> i8 {
panic!("Not implemented")
}
pub fn handle_to_uint8(&mut self, opnd: &APIMuValue) -> u8 {
panic!("Not implemented")
}
pub fn handle_to_sint16(&mut self, opnd: &APIMuValue) -> i16 {
panic!("Not implemented")
}
pub fn handle_to_uint16(&mut self, opnd: &APIMuValue) -> u16 {
panic!("Not implemented")
}
pub fn handle_to_sint32(&mut self, opnd: &APIMuValue) -> i32 {
panic!("Not implemented")
}
pub fn handle_to_uint32(&mut self, opnd: &APIMuValue) -> u32 {
panic!("Not implemented")
}
pub fn handle_to_sint64(&mut self, opnd: &APIMuValue) -> i64 {
panic!("Not implemented")
}
pub fn handle_to_uint64(&mut self, opnd: &APIMuValue) -> u64 {
panic!("Not implemented")
}
pub fn handle_to_float(&mut self, opnd: &APIMuValue) -> f32 {
panic!("Not implemented")
}
pub fn handle_to_double(&mut self, opnd: &APIMuValue) -> f64 {
panic!("Not implemented")
}
pub fn handle_to_ptr(&mut self, opnd: &APIMuValue) -> CMuCPtr {
panic!("Not implemented")
}
pub fn handle_to_fp(&mut self, opnd: &APIMuValue) -> CMuCFP {
panic!("Not implemented")
}
pub fn handle_from_const(&mut self, id: MuID) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_global(&mut self, id: MuID) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_func(&mut self, id: MuID) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn handle_from_expose(&mut self, id: MuID) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn delete_value(&mut self, opnd: &APIMuValue) {
panic!("Not implemented")
}
pub fn ref_eq(&mut self, lhs: &APIMuValue, rhs: &APIMuValue) -> bool {
panic!("Not implemented")
}
pub fn ref_ult(&mut self, lhs: &APIMuValue, rhs: &APIMuValue) -> bool {
panic!("Not implemented")
}
pub fn extract_value(&mut self, str: &APIMuValue, index: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn insert_value(&mut self, str: &APIMuValue, index: c_int, newval: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn extract_element(&mut self, str: &APIMuValue, index: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn insert_element(&mut self, str: &APIMuValue, index: &APIMuValue, newval: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn new_fixed(&mut self, mu_type: MuID) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn new_hybrid(&mut self, mu_type: MuID, length: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn refcast(&mut self, opnd: &APIMuValue, new_type: MuID) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn get_iref(&mut self, opnd: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn get_field_iref(&mut self, opnd: &APIMuValue, field: c_int) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn get_elem_iref(&mut self, opnd: &APIMuValue, index: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn shift_iref(&mut self, opnd: &APIMuValue, offset: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn get_var_part_iref(&mut self, opnd: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn load(&mut self, ord: CMuMemOrd, loc: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn store(&mut self, ord: CMuMemOrd, loc: &APIMuValue, newval: &APIMuValue) {
panic!("Not implemented")
}
pub fn cmpxchg(&mut self, ord_succ: CMuMemOrd, ord_fail: CMuMemOrd, weak: bool, loc: &APIMuValue, expected: &APIMuValue, desired: &APIMuValue, is_succ: *mut CMuBool) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn atomicrmw(&mut self, ord: CMuMemOrd, op: CMuAtomicRMWOptr, loc: &APIMuValue, opnd: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn fence(&mut self, ord: CMuMemOrd) {
panic!("Not implemented")
}
pub fn new_stack(&mut self, func: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn new_thread_nor(&mut self, stack: &APIMuValue, threadlocal: Option<&APIMuValue>, vals: Vec<&APIMuValue>) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn new_thread_exc(&mut self, stack: &APIMuValue, threadlocal: Option<&APIMuValue>, exc: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn kill_stack(&mut self, stack: &APIMuValue) {
panic!("Not implemented")
}
pub fn set_threadlocal(&mut self, thread: &APIMuValue, threadlocal: &APIMuValue) {
panic!("Not implemented")
}
pub fn get_threadlocal(&mut self, thread: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn new_cursor(&mut self, stack: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn next_frame(&mut self, cursor: &APIMuValue) {
panic!("Not implemented")
}
pub fn copy_cursor(&mut self, cursor: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn close_cursor(&mut self, cursor: &APIMuValue) {
panic!("Not implemented")
}
pub fn cur_func(&mut self, cursor: &APIMuValue) -> MuID {
panic!("Not implemented")
}
pub fn cur_func_ver(&mut self, cursor: &APIMuValue) -> MuID {
panic!("Not implemented")
}
pub fn cur_inst(&mut self, cursor: &APIMuValue) -> MuID {
panic!("Not implemented")
}
pub fn dump_keepalives(&mut self, cursor: &APIMuValue, results: *mut CMuValue) {
panic!("Not implemented")
}
pub fn pop_frames_to(&mut self, cursor: &APIMuValue) {
panic!("Not implemented")
}
pub fn push_frame(&mut self, stack: &APIMuValue, func: &APIMuValue) {
panic!("Not implemented")
}
pub fn tr64_is_fp(&mut self, value: &APIMuValue) -> bool {
panic!("Not implemented")
}
pub fn tr64_is_int(&mut self, value: &APIMuValue) -> bool {
panic!("Not implemented")
}
pub fn tr64_is_ref(&mut self, value: &APIMuValue) -> bool {
panic!("Not implemented")
}
pub fn tr64_to_fp(&mut self, value: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn tr64_to_int(&mut self, value: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn tr64_to_ref(&mut self, value: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn tr64_to_tag(&mut self, value: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn tr64_from_fp(&mut self, value: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn tr64_from_int(&mut self, value: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn tr64_from_ref(&mut self, reff: &APIMuValue, tag: &APIMuValue) -> *const APIMuValue {
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")
}
pub fn pin(&mut self, loc: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn unpin(&mut self, loc: &APIMuValue) {
panic!("Not implemented")
}
pub fn get_addr(&mut self, loc: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn expose(&mut self, func: &APIMuValue, call_conv: CMuCallConv, cookie: &APIMuValue) -> *const APIMuValue {
panic!("Not implemented")
}
pub fn unexpose(&mut self, call_conv: CMuCallConv, value: &APIMuValue) {
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
}
pub fn make_boot_image(&mut self, whitelist: Vec<MuID>, primordial_func: Option<&APIMuValue>, primordial_stack: Option<&APIMuValue>, primordial_threadlocal: Option<&APIMuValue>, sym_fields: Vec<&APIMuValue>, sym_strings: Vec<String>, reloc_fields: Vec<&APIMuValue>, reloc_strings: Vec<String>, output_file: String) {
panic!("Not implemented")
}
}
use super::common::*;
pub struct MuVM {
// The actual VM
pub vm: VM,
// Cache C strings. The C client expects `char*` from `name_of`. We assume the client won't
// call `name_of` very often, so that we don't need to initialise this hashmap on startup.
name_cache: Mutex<HashMap<MuID, CString>>,
}
/**
* Implement the methods of MuVM. Most methods implement the C-level methods, and others are
* rust-level helpers. Most methods are forwarded to the underlying `VM.*` methods.
*/
impl MuVM {
/**
* Create a new micro VM instance from scratch.
*/
pub fn new() -> MuVM {
MuVM {
vm: VM::new(),
// Cache C strings. The C client expects `char*` from `name_of`. We assume the client
// won't call `name_of` very often, so that we don't need to initialise this hashmap on
// startup.
//
// RwLock won't work because Rust will not let me release the lock after reading
// because other threads will remove that element from the cache, even though I only
// monotonically add elements into the `name_cache`. I can't upgrade the lock from read
// lock to write lock, otherwise it will deadlock.
name_cache: Mutex::new(HashMap::new()),
}
}
pub fn new_context(&self) -> *mut CMuCtx {
info!("Creating MuCtx...");
let ctx = MuCtx::new(self);
let ctx_ptr = Box::into_raw(ctx);
debug!("The MuCtx address: {:?}", ctx_ptr);
let cctx = make_new_MuCtx(ctx_ptr as *mut c_void);
debug!("The C-visible CMuCtx struct address: {:?}", cctx);
unsafe{ (*ctx_ptr).c_struct = cctx; }
cctx
}
pub fn id_of(&self, name: MuName) -> MuID {
self.vm.id_of_by_refstring(&name)
}
pub fn name_of(&self, id: MuID) -> CMuCString {
let mut map = self.name_cache.lock().unwrap();
let cname = map.entry(id).or_insert_with(|| {
let rustname = self.vm.name_of(id);
CString::new(rustname).unwrap()
});
cname.as_ptr()
}
pub fn set_trap_handler(&self, trap_handler: CMuTrapHandler, userdata: CMuCPtr) {
panic!("Not implemented")
}
}
/**
* Create a micro VM instance, and expose it as a C-visible `*mut CMuVM` pointer.
*
* NOTE: When used as an API (such as in tests), please use `mu::vm::api::mu_fastimpl_new` instead.
*
* This method is not part of the API defined by the Mu spec. It is used **when the client starts
* the process and creates the micor VM**. For example, it is used if the client wants to build
* boot images, or if the client implements most of its parts in C and onlu uses the micro VM as
* the JIT compiler.
*
* The boot image itself should use `VM::resume_vm` to restore the saved the micro VM. There is no
* need in the boot image itself to expose the `MuVM` structure to the trap handler. Trap handlers
* only see `MuCtx`, and it is enough for most of the works.
*/
#[no_mangle]
pub extern fn mu_fastimpl_new() -> *mut CMuVM {
info!("Creating Mu micro VM fast implementation instance...");
let mvm = Box::new(MuVM::new());
let mvm_ptr = Box::into_raw(mvm);
debug!("The MuVM instance address: {:?}", mvm_ptr);
let c_mvm = make_new_MuVM(mvm_ptr as *mut c_void);
debug!("The C-visible CMuVM struct address: {:?}", c_mvm);
c_mvm
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment