Commit b362e1ec authored by Kunshan Wang's avatar Kunshan Wang

IRBuilder: Builds struct with recursive uptrs.

parent a68b08a4
......@@ -152,6 +152,10 @@ impl fmt::Display for StructType_ {
}
impl StructType_ {
// The IR builder needs to create StructType objects, too.
pub fn new(tys: Vec<P<MuType>>) -> StructType_ {
StructType_ { tys: tys }
}
pub fn set_tys(&mut self, mut list: Vec<P<MuType>>) {
self.tys.clear();
self.tys.append(&mut list);
......
......@@ -448,6 +448,7 @@ struct BundleLoader<'lb, 'lvm> {
visited: HashSet<MuID>,
built_types: IdPMap<MuType>,
built_sigs: IdPMap<MuFuncSig>,
struct_id_tags: Vec<(MuID, MuName)>,
}
fn load_bundle(b: &mut MuIRBuilder) {
......@@ -459,6 +460,7 @@ fn load_bundle(b: &mut MuIRBuilder) {
visited: Default::default(),
built_types: Default::default(),
built_sigs: Default::default(),
struct_id_tags: Default::default(),
};
bl.load_bundle();
......@@ -467,13 +469,25 @@ fn load_bundle(b: &mut MuIRBuilder) {
impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
fn load_bundle(&mut self) {
for id in self.b.bundle.types.keys() {
self.ensure_type_top(*id);
if !self.visited.contains(id) {
self.build_type(*id)
}
}
let struct_id_tags = self.struct_id_tags.drain(..).collect::<Vec<_>>();
for (id, ref tag) in struct_id_tags {
self.fill_struct(id, tag)
}
}
fn ensure_type_top(&mut self, id: MuID) {
if !self.visited.contains(&id) {
self.build_type(id)
fn name_from_id(id: MuID, hint: &str) -> String {
format!("@uvm.unnamed{}{}", hint, id)
}
fn get_name_or_make(&self, id: MuID, hint: &str) -> String {
match self.b.id_name_map.get(&id) {
Some(n) => n.clone(),
None => BundleLoader::name_from_id(id, hint),
}
}
......@@ -485,12 +499,17 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
trace!("Building type {} {:?}", id, ty);
let impl_ty = MuType::new(id, match **ty {
NodeType::TypeInt { id, len } => {
MuType_::int(len as usize)
NodeType::TypeInt { id: _, len: len } => {
MuType_::Int(len as usize)
},
NodeType::TypeUPtr { id, ty: toty } => {
NodeType::TypeUPtr { id: _, ty: toty } => {
let toty_i = self.ensure_type_rec(toty);
MuType_::uptr(toty_i)
MuType_::UPtr(toty_i)
},
NodeType::TypeStruct { id: _, fieldtys: _ } => {
let tag = self.get_name_or_make(id, "struct");
self.struct_id_tags.push((id, tag.clone()));
MuType_::Struct(tag)
},
ref t => panic!("{:?} not implemented", t),
});
......@@ -516,5 +535,35 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
}
fn fill_struct(&mut self, id: MuID, tag: &MuName) {
let ty = self.b.bundle.types.get(&id).unwrap();
trace!("Filling struct {} {:?}", id, ty);
match **ty {
NodeType::TypeStruct { id: _, fieldtys: ref fieldtys } => {
let fieldtys_impl = fieldtys.iter().map(|fid| {
self.ensure_type_rec(*fid)
}).collect::<Vec<_>>();
let struct_ty_ = StructType_::new(fieldtys_impl);
match STRUCT_TAG_MAP.read().unwrap().get(tag) {
Some(old_struct_ty_) => {
if struct_ty_ != *old_struct_ty_ {
panic!("trying to insert {:?} as {}, while the old struct is defined as {:?}",
struct_ty_, tag, old_struct_ty_)
}
},
None => {}
}
STRUCT_TAG_MAP.write().unwrap().insert(tag.clone(), struct_ty_);
trace!("Struct {} filled: {:?}", id,
STRUCT_TAG_MAP.read().unwrap().get(tag));
},
ref t => panic!("{} {:?} should be a Struct type", id, ty),
}
}
}
......@@ -88,10 +88,20 @@ fn test_types_sigs_loading() {
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"));
let id4 = ((*b).gen_sym)(b, csp.get("@str1"));
let id5 = ((*b).gen_sym)(b, ptr::null_mut());
let id6 = ((*b).gen_sym)(b, csp.get("@str2"));
let id7 = ((*b).gen_sym)(b, csp.get("@pstr2"));
((*b).new_type_uptr)(b, id3, id2);
((*b).new_type_int)(b, id2, 32);
((*b).new_type_int)(b, id1, 8);
((*b).new_type_int)(b, id2, 32);
((*b).new_type_uptr)(b, id3, id2);
((*b).new_type_struct)(b, id4, ptr::null_mut(), 0);
((*b).new_type_struct)(b, id5, ptr::null_mut(), 0);
let mut fields = vec![id3, id7];
((*b).new_type_struct)(b, id6, fields.as_mut_ptr(), fields.len());
((*b).new_type_uptr)(b, id7, id6);
((*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