Commit a68b08a4 authored by Kunshan Wang's avatar Kunshan Wang

IRBuilder: Builds int and uptr

Also resolves dependency
parent 3add9719
#![allow(non_snake_case)]
#![allow(dead_code)]
use super::deps::*;
use super::common::*;
//pub type MuID = usize;
pub type MuTypeNode = MuID;
......
......@@ -12,6 +12,7 @@
mod muvm;
mod muctx;
mod muirbuilder;
mod irnodes;
pub use self::muvm::*;
pub use self::muctx::*;
......@@ -33,12 +34,12 @@ mod common {
pub use super::muvm::*;
pub use super::muctx::*;
pub use super::muirbuilder::*;
pub use super::irnodes::*;
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::*;
......
......@@ -442,46 +442,54 @@ impl MuIRBuilder {
type IdPMap<T> = HashMap<MuID, P<T>>;
fn load_bundle(b: &mut MuIRBuilder) {
let mut visited: HashSet<MuID> = Default::default();
let mut built_types: IdPMap<MuType> = Default::default();
let mut built_sigs: IdPMap<MuFuncSig> = Default::default();
struct BundleLoader<'lb, 'lvm> {
b: &'lb MuIRBuilder,
vm: &'lvm VM,
visited: HashSet<MuID>,
built_types: IdPMap<MuType>,
built_sigs: IdPMap<MuFuncSig>,
}
fn load_bundle(b: &mut MuIRBuilder) {
let vm = b.get_vm();
for (id, ty) in &b.bundle.types {
ensure_type_top(*id, ty, b, &mut visited, &mut built_types, &mut built_sigs, &vm);
}
let mut bl = BundleLoader {
b: b,
vm: vm,
visited: Default::default(),
built_types: Default::default(),
built_sigs: Default::default(),
};
bl.load_bundle();
}
fn ensure_type_top(id: MuID,
ty: &Box<NodeType>,
b: &MuIRBuilder,
visited: &mut HashSet<MuID>,
built_types: &mut IdPMap<MuType>,
built_sigs: &mut IdPMap<MuFuncSig>,
vm: &VM) {
if !visited.contains(&id) {
build_type(id, ty, b, visited, built_types, built_sigs, vm)
impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
fn load_bundle(&mut self) {
for id in self.b.bundle.types.keys() {
self.ensure_type_top(*id);
}
}
}
fn build_type(id: MuID,
ty: &Box<NodeType>,
b: &MuIRBuilder,
visited: &mut HashSet<MuID>,
built_types: &mut IdPMap<MuType>,
built_sigs: &mut IdPMap<MuFuncSig>,
vm: &VM) {
fn ensure_type_top(&mut self, id: MuID) {
if !self.visited.contains(&id) {
self.build_type(id)
}
}
fn build_type(&mut self, id: MuID) {
self.visited.insert(id);
let ty = self.b.bundle.types.get(&id).unwrap();
trace!("Building type {} {:?}", id, ty);
visited.insert(id);
let impl_ty = MuType::new(id, match **ty {
NodeType::TypeInt { id, len } => {
MuType_::int(len as usize)
},
NodeType::TypeUPtr { id, ty: toty } => {
let toty_i = ensure_type_rec(toty, ty, b, visited, built_types, built_sigs, vm);
let toty_i = self.ensure_type_rec(toty);
MuType_::uptr(toty_i)
},
ref t => panic!("{:?} not implemented", t),
......@@ -489,28 +497,24 @@ fn build_type(id: MuID,
trace!("Type built: {} {:?}", id, impl_ty);
built_types.insert(id, P(impl_ty));
}
self.built_types.insert(id, P(impl_ty));
}
fn ensure_type_rec(id: MuID,
ty: &Box<NodeType>,
b: &MuIRBuilder,
visited: &mut HashSet<MuID>,
built_types: &mut IdPMap<MuType>,
built_sigs: &mut IdPMap<MuFuncSig>,
vm: &VM) -> P<MuType> {
if b.bundle.types.contains_key(&id) {
if visited.contains(&id) {
match built_types.get(&id) {
fn ensure_type_rec(&mut self, id: MuID) -> P<MuType> {
if self.b.bundle.types.contains_key(&id) {
if self.visited.contains(&id) {
match self.built_types.get(&id) {
Some(t) => t.clone(),
None => panic!("Cyclic types found. id: {}", id)
}
} else {
build_type(id, ty, b, visited, built_types, built_sigs, vm);
built_types.get(&id).unwrap().clone()
self.build_type(id);
self.built_types.get(&id).unwrap().clone()
}
} else {
vm.get_type(id)
self.vm.get_type(id)
}
}
}
pub mod api_c; // This is pub because `api_c` can be used directly. It is just an interface.
mod api_bridge; // This is mostly auto-generatd code, and should not be used externally.
mod api_impl; // Mostly private.
mod irnodes;
pub use self::api_impl::mu_fastimpl_new;
......
......@@ -16,6 +16,7 @@ use self::mu::vm::api::*;
use std::mem;
use std::ptr;
use std::ffi::CString;
use std::os::raw::c_char;
#[test]
#[allow(unused_variables)]
......@@ -55,9 +56,24 @@ fn test_startup_shutdown() {
}
}
#[derive(Default)]
struct CStringPool {
strings: Vec<CString>,
}
impl CStringPool {
fn get(&mut self, s: &str) -> *const c_char {
self.strings.push(CString::new(s).unwrap());
self.strings.last().unwrap().as_ptr()
}
}
#[test]
#[allow(unused_variables)]
fn test_types_sigs_loading() {
let mut csp: CStringPool = Default::default();
unsafe {
simple_logger::init_with_level(log::LogLevel::Trace).ok();
......@@ -69,13 +85,13 @@ fn test_types_sigs_loading() {
let b = ((*ctx).new_ir_builder)(ctx);
let id1 = ((*b).gen_sym)(b, ptr::null_mut());
let id2 = ((*b).gen_sym)(b, CString::new("@id2").unwrap().as_ptr());
let id3 = ((*b).gen_sym)(b, ptr::null_mut());
let id1 = ((*b).gen_sym)(b, csp.get("@i8"));
let id2 = ((*b).gen_sym)(b, csp.get("@i32"));
let id3 = ((*b).gen_sym)(b, csp.get("@pi32"));
((*b).new_type_int)(b, id1, 8);
((*b).new_type_int)(b, id2, 32);
((*b).new_type_uptr)(b, id3, id2);
((*b).new_type_int)(b, id2, 32);
((*b).new_type_int)(b, id1, 8);
((*b).load)(b);
((*ctx).close_context)(ctx);
......
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