GitLab will be partched to the latest stable version on 15 July 2020 at 2.00pm (AEDT) to 2.30pm (AEDT) due to Security Patch Availability. During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit 50b5f20f authored by Kunshan Wang's avatar Kunshan Wang

IRBuilder: fixed Struct, Hybrid and GetFieldIRef

parent d9912d25
......@@ -264,10 +264,10 @@ impl MuType_ {
MuType_::Struct(tag)
}
pub fn mustruct_put(tag: MuName, mut list: Vec<P<MuType>>) {
pub fn mustruct_put(tag: &MuName, mut list: Vec<P<MuType>>) {
let mut map_guard = STRUCT_TAG_MAP.write().unwrap();
match map_guard.get_mut(&tag) {
match map_guard.get_mut(tag) {
Some(struct_ty_) => {
struct_ty_.tys.clear();
struct_ty_.tys.append(&mut list);
......@@ -303,10 +303,10 @@ impl MuType_ {
MuType_::Hybrid(tag)
}
pub fn hybrid_put(tag: HybridTag, mut fix_tys: Vec<P<MuType>>, var_ty: P<MuType>) {
pub fn hybrid_put(tag: &HybridTag, mut fix_tys: Vec<P<MuType>>, var_ty: P<MuType>) {
let mut map_guard = HYBRID_TAG_MAP.write().unwrap();
match map_guard.get_mut(&tag) {
match map_guard.get_mut(tag) {
Some(hybrid_ty_) => {
hybrid_ty_.fix_tys.clear();
hybrid_ty_.fix_tys.append(&mut fix_tys);
......
......@@ -544,7 +544,7 @@ struct BundleLoader<'lb, 'lvm> {
built_globals: IdPMap<Value>,
built_funcs: IdBMap<MuFunction>,
built_funcvers: IdBMap<MuFunctionVersion>,
struct_id_tags: Vec<(MuID, MuName)>,
struct_hybrid_id_tags: Vec<(MuID, MuName)>,
built_refi64: Option<P<MuType>>,
built_i1: Option<P<MuType>>,
built_i64: Option<P<MuType>>,
......@@ -570,7 +570,7 @@ fn load_bundle(b: &mut MuIRBuilder) {
built_globals: Default::default(),
built_funcs: Default::default(),
built_funcvers: Default::default(),
struct_id_tags: Default::default(),
struct_hybrid_id_tags: Default::default(),
built_refi64: Default::default(),
built_i1: Default::default(),
built_i64: Default::default(),
......@@ -778,13 +778,16 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
fn ensure_names(&mut self) {
// Make sure structs have names because struct names are used to resolve cyclic
// Make sure structs and hybrids have names because names are used to resolve cyclic
// dependencies.
for (id, ty) in &self.b.bundle.types {
match **ty {
NodeType::TypeStruct { id: _, fieldtys: _ } => {
self.ensure_name(*id, "struct");
},
NodeType::TypeHybrid { id: _, fixedtys: _, varty: _ } => {
self.ensure_name(*id, "struct");
},
_ => {}
}
}
......@@ -820,9 +823,9 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
}
let struct_id_tags = self.struct_id_tags.drain(..).collect::<Vec<_>>();
for (id, ref tag) in struct_id_tags {
self.fill_struct(id, tag)
let struct_hybrid_id_tags = self.struct_hybrid_id_tags.drain(..).collect::<Vec<_>>();
for (id, ref tag) in struct_hybrid_id_tags {
self.fill_struct_hybrid(id, tag)
}
for id in self.b.bundle.sigs.keys() {
......@@ -877,11 +880,14 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
},
NodeType::TypeStruct { id: _, fieldtys: _ } => {
let tag = self.get_name(id);
self.struct_id_tags.push((id, tag.clone()));
MuType_::Struct(tag)
self.struct_hybrid_id_tags.push((id, tag.clone()));
MuType_::mustruct_empty(tag)
// MuType_::Struct(tag)
},
NodeType::TypeHybrid { id: _, ref fixedtys, varty } => {
unimplemented!()
NodeType::TypeHybrid { id: _, fixedtys: _, varty: _ } => {
let tag = self.get_name(id);
self.struct_hybrid_id_tags.push((id, tag.clone()));
MuType_::hybrid_empty(tag)
// let impl_fixedtys = fixedtys.iter().map(|t| self.ensure_type_rec(*t)).collect::<Vec<_>>();
// let impl_varty = self.ensure_type_rec(varty);
// MuType_::Hybrid(impl_fixedtys, impl_varty)
......@@ -955,34 +961,35 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
}
fn fill_struct(&mut self, id: MuID, tag: &MuName) {
fn fill_struct_hybrid(&mut self, id: MuID, tag: &MuName) {
let ty = self.b.bundle.types.get(&id).unwrap();
trace!("Filling struct {} {:?}", id, ty);
trace!("Filling struct or hybrid {} {:?}", id, ty);
match **ty {
NodeType::TypeStruct { id: _, ref fieldtys } => {
NodeType::TypeStruct { id: _, 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_);
MuType_::mustruct_put(tag, fieldtys_impl);
trace!("Struct {} filled: {:?}", id,
STRUCT_TAG_MAP.read().unwrap().get(tag));
},
ref t => panic!("{} {:?} should be a Struct type", id, ty),
NodeType::TypeHybrid { id: _, ref fixedtys, varty } => {
let fixedtys_impl = fixedtys.iter().map(|fid| {
self.ensure_type_rec(*fid)
}).collect::<Vec<_>>();
let varty_impl = self.ensure_type_rec(varty);
MuType_::hybrid_put(tag, fixedtys_impl, varty_impl);
trace!("Hybrid {} filled: {:?}", id,
HYBRID_TAG_MAP.read().unwrap().get(tag));
},
ref t => panic!("{} {:?} should be a Struct or Hybrid type", id, ty),
}
}
......@@ -1530,28 +1537,30 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
},
NodeInst::NodeGetFieldIRef { id: _, result_id, is_ptr, refty, index, opnd } => {
unimplemented!()
// let impl_opnd = self.get_treenode(fcb, opnd);
// let impl_index = self.ensure_constint_of(index as u64);
// let refty_node = self.b.bundle.types.get(&refty).unwrap();
// let field_ty_id = match **refty_node {
// NodeType::TypeStruct { id: _, ref fieldtys } => {
// fieldtys[index as usize]
// },
// ref t => panic!("GETFIELDIREF {}: Expected struct type. actual: {:?}", id, t)
// };
// let impl_rvtype = self.ensure_iref_or_uptr(field_ty_id, is_ptr);
// let impl_rv = self.new_ssa(fcb, result_id, impl_rvtype).clone_value();
// Instruction {
// hdr: hdr,
// value: Some(vec![impl_rv]),
// ops: RwLock::new(vec![impl_opnd, impl_index]),
// v: Instruction_::GetFieldIRef {
// is_ptr: is_ptr,
// base: 0,
// index: 1,
// },
// }
let impl_opnd = self.get_treenode(fcb, opnd);
let index = index as usize;
let refty_node = self.b.bundle.types.get(&refty).unwrap();
let field_ty_id = match **refty_node {
NodeType::TypeStruct { id: _, ref fieldtys } => {
fieldtys[index]
},
NodeType::TypeHybrid { id: _, ref fixedtys, varty: _ } => {
fixedtys[index]
},
ref t => panic!("GETFIELDIREF {}: Expected struct or hybrid type. actual: {:?}", id, t)
};
let impl_rvtype = self.ensure_iref_or_uptr(field_ty_id, is_ptr);
let impl_rv = self.new_ssa(fcb, result_id, impl_rvtype).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: RwLock::new(vec![impl_opnd]),
v: Instruction_::GetFieldIRef {
is_ptr: is_ptr,
base: 0,
index: index,
},
}
},
NodeInst::NodeGetElemIRef { id: _, result_id, is_ptr, refty, indty: _, opnd, index } => {
let impl_opnd = self.get_treenode(fcb, opnd);
......
......@@ -110,6 +110,13 @@ fn test_types_sigs_loading() {
ptys.as_mut_ptr(), ptys.len(),
rtys.as_mut_ptr(), rtys.len());
((*b).new_type_ufuncptr)(b, id9, id8);
let id10 = ((*b).gen_sym)(b, csp.get("@hyb1"));
let id11 = ((*b).gen_sym)(b, csp.get("@rhyb1"));
let mut fixeds = vec![id2, id2];
((*b).new_type_hybrid)(b, id10, fixeds.as_mut_ptr(), fixeds.len(), id1);
((*b).new_type_ref)(b, id11, id10);
((*b).load)(b);
((*ctx).close_context)(ctx);
......@@ -530,11 +537,28 @@ fn test_insts_new() {
let b = ((*ctx).new_ir_builder)(ctx);
let id_float = ((*b).gen_sym)(b, csp.get("@float"));
let id_i8 = ((*b).gen_sym)(b, csp.get("@i8"));
let id_i32 = ((*b).gen_sym)(b, csp.get("@i32"));
let id_i64 = ((*b).gen_sym)(b, csp.get("@i64"));
let id_s = ((*b).gen_sym)(b, csp.get("@s"));
let id_a = ((*b).gen_sym)(b, csp.get("@a"));
let id_h = ((*b).gen_sym)(b, csp.get("@h"));
let id_sig = ((*b).gen_sym)(b, csp.get("@sig"));
let id_func = ((*b).gen_sym)(b, csp.get("@func"));
((*b).new_type_float)(b, id_float);
((*b).new_type_int)(b, id_i8, 8);
((*b).new_type_int)(b, id_i32, 32);
((*b).new_type_int)(b, id_i64, 64);
{
let mut fields = vec![id_i32, id_a, id_i64];
((*b).new_type_struct)(b, id_s, fields.as_mut_ptr(), fields.len());
((*b).new_type_hybrid)(b, id_h, fields.as_mut_ptr(), fields.len(), id_i8);
}
((*b).new_type_array)(b, id_a, id_float, 4);
let mut ptys = vec![];
let mut rtys = vec![];
......@@ -542,6 +566,11 @@ fn test_insts_new() {
ptys.as_mut_ptr(), ptys.len(),
rtys.as_mut_ptr(), rtys.len());
let id_consti64_3 = ((*b).gen_sym)(b, csp.get("@CONSTI64_3"));
((*b).new_const_int)(b, id_consti64_3, id_i64, 3);
let id_consti64_4 = ((*b).gen_sym)(b, csp.get("@CONSTI64_4"));
((*b).new_const_int)(b, id_consti64_4, id_i64, 4);
((*b).new_func)(b, id_func, id_sig);
let id_funcver = ((*b).gen_sym)(b, csp.get("@func.v1"));
......@@ -557,18 +586,57 @@ fn test_insts_new() {
let mut args = vec![];
let mut argtys = vec![];
let id_new = ((*b).gen_sym)(b, csp.get("@func.v1.entry.new"));
let id_ret = ((*b).gen_sym)(b, csp.get("@func.v1.entry.ret"));
let mut insts = vec![id_new, id_ret];
let id_new = ((*b).gen_sym)(b, csp.get("@func.v1.entry.new"));
let id_newhybrid = ((*b).gen_sym)(b, csp.get("@func.v1.entry.newhybrid"));
let id_getiref1 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.getiref1"));
let id_getiref2 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.getiref2"));
let id_getfieldiref1 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.getfieldiref1"));
let id_getfieldiref2 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.getfieldiref2"));
let id_getelemiref = ((*b).gen_sym)(b, csp.get("@func.v1.entry.getelemiref"));
let id_getvarpartiref = ((*b).gen_sym)(b, csp.get("@func.v1.entry.getvarpartiref"));
let id_shiftiref = ((*b).gen_sym)(b, csp.get("@func.v1.entry.shiftiref"));
let id_ret = ((*b).gen_sym)(b, csp.get("@func.v1.entry.ret"));
let mut insts = vec![
id_new,
id_newhybrid,
id_getiref1,
id_getiref2,
id_getfieldiref1,
id_getfieldiref2,
id_getelemiref,
id_getvarpartiref,
id_shiftiref,
id_ret,
];
((*b).new_bb)(b, id_entry,
args.as_mut_ptr(), argtys.as_mut_ptr(), args.len(),
0,
insts.as_mut_ptr(), insts.len());
let id_x = ((*b).gen_sym)(b, csp.get("@func.v1.entry.x"));
let id_v_r1 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.r1"));
let id_v_r2 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.r2"));
let id_v_i1 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.i1"));
let id_v_i2 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.i2"));
let id_v_f1 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.f1"));
let id_v_f2 = ((*b).gen_sym)(b, csp.get("@func.v1.entry.f2"));
let id_v_e = ((*b).gen_sym)(b, csp.get("@func.v1.entry.e"));
let id_v_v = ((*b).gen_sym)(b, csp.get("@func.v1.entry.v"));
let id_v_s = ((*b).gen_sym)(b, csp.get("@func.v1.entry.s"));
((*b).new_new)(b, id_new, id_v_r1, id_s, 0);
((*b).new_newhybrid)(b, id_newhybrid, id_v_r2, id_h, id_i64, id_consti64_4, 0);
((*b).new_getiref)(b, id_getiref1, id_v_i1, id_s, id_v_r1);
((*b).new_getiref)(b, id_getiref2, id_v_i2, id_h, id_v_r2);
((*b).new_getfieldiref)(b, id_getfieldiref1, id_v_f1, 0, id_s, 1, id_v_i1);
((*b).new_getfieldiref)(b, id_getfieldiref2, id_v_f2, 0, id_h, 2, id_v_i2);
((*b).new_getelemiref)(b, id_getelemiref, id_v_e, 0, id_a, id_i64, id_v_f1, id_consti64_3);
((*b).new_new)(b, id_new, id_x, id_i32, 0);
((*b).new_getvarpartiref)(b, id_getvarpartiref, id_v_v, 0, id_h, id_v_i2);
((*b).new_shiftiref)(b, id_shiftiref, id_v_s, 0, id_i8, id_i64, id_v_v, id_consti64_3);
{
let mut args = vec![];
......
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