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