Commit 6c505ac1 authored by qinsoon's avatar qinsoon

[wip] refactor: move a few functions from mod types to MuType

parent dba7a91a
......@@ -98,28 +98,166 @@ impl MuType {
}
}
pub fn get_struct_hybrid_tag(&self) -> Option<MuName> {
pub fn is_ref(&self) -> bool {
match self.v {
MuType_::Hybrid(ref name)
| MuType_::Struct(ref name) => Some(name.clone()),
_ => None
MuType_::Ref(_) => true,
_ => false
}
}
pub fn is_ref(&self) -> bool {
pub fn is_iref(&self) -> bool {
match self.v {
MuType_::Ref(_) => true,
MuType_::IRef(_) => true,
_ => false
}
}
pub fn is_iref(&self) -> bool {
pub fn is_fp(&self) -> bool {
match self.v {
MuType_::Float | MuType_::Double => true,
_ => false
}
}
pub fn is_float(&self) -> bool {
match self.v {
MuType_::Float => true,
_ => false
}
}
pub fn is_double(&self) -> bool {
match self.v {
MuType_::Double => true,
_ => false
}
}
/// is a type raw pointer?
pub fn is_ptr(&self) -> bool {
match self.v {
MuType_::UPtr(_) | MuType_::UFuncPtr(_) => true,
_ => false
}
}
/// this a type reference type (located in heap)?
pub fn is_reference(&self) -> bool {
match self.v {
MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_) => true,
_ => false
}
}
/// this is a aggregated type (consited of other types)
pub fn is_aggregate(&self) -> bool {
match self.v {
MuType_::Struct(_)
| MuType_::Hybrid(_)
| MuType_::Array(_, _) => true,
_ => false
}
}
/// is a type scalar type?
pub fn is_scalar(&self) -> bool {
match self.v {
MuType_::Int(_)
| MuType_::Float
| MuType_::Double
| MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_)
| MuType_::FuncRef(_)
| MuType_::UFuncPtr(_)
| MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64
| MuType_::UPtr(_) => true,
_ => false
}
}
/// is a type traced by the garbage collector?
/// Note: An aggregated type is traced if any of its part is traced.
pub fn is_traced(&self) -> bool {
match self.v {
MuType_::Ref(_) => true,
MuType_::IRef(_) => true,
MuType_::WeakRef(_) => true,
MuType_::Array(ref elem_ty, _)
| MuType_::Vector(ref elem_ty, _) => elem_ty.is_traced(),
MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64 => true,
MuType_::Hybrid(ref tag) => {
let map = HYBRID_TAG_MAP.read().unwrap();
let hybrid_ty = map.get(tag).unwrap();
let ref fix_tys = hybrid_ty.fix_tys;
let ref var_ty = hybrid_ty.var_ty;
var_ty.is_traced() ||
fix_tys.into_iter().map(|ty| ty.is_traced())
.fold(false, |ret, this| ret || this)
},
MuType_::Struct(ref tag) => {
let map = STRUCT_TAG_MAP.read().unwrap();
let struct_ty = map.get(tag).unwrap();
let ref field_tys = struct_ty.tys;
field_tys.into_iter().map(|ty| ty.is_traced())
.fold(false, |ret, this| ret || this)
},
_ => false
}
}
/// is a type native safe?
/// Note: An aggregated type is native safe if all of its parts are native safe.
pub fn is_native_safe(&self) -> bool {
match self.v {
MuType_::Int(_) => true,
MuType_::Float => true,
MuType_::Double => true,
MuType_::Void => true,
MuType_::Array(ref elem_ty, _)
| MuType_::Vector(ref elem_ty, _) => elem_ty.is_native_safe(),
MuType_::UPtr(_) => true,
MuType_::UFuncPtr(_) => true,
MuType_::Hybrid(ref tag) => {
let map = HYBRID_TAG_MAP.read().unwrap();
let hybrid_ty = map.get(tag).unwrap();
let ref fix_tys = hybrid_ty.fix_tys;
let ref var_ty = hybrid_ty.var_ty;
var_ty.is_native_safe() &&
fix_tys.into_iter().map(|ty| ty.is_native_safe())
.fold(true, |ret, this| ret && this)
},
MuType_::Struct(ref tag) => {
let map = STRUCT_TAG_MAP.read().unwrap();
let struct_ty = map.get(tag).unwrap();
let ref field_tys = struct_ty.tys;
field_tys.into_iter().map(|ty| ty.is_native_safe())
.fold(true, |ret, this| ret && this)
},
_ => false
}
}
pub fn get_struct_hybrid_tag(&self) -> Option<MuName> {
match self.v {
MuType_::Hybrid(ref name)
| MuType_::Struct(ref name) => Some(name.clone()),
_ => None
}
}
pub fn get_elem_ty(&self) -> Option<P<MuType>> {
match self.v {
MuType_::Array(ref elem_ty, _) => Some(elem_ty.clone()),
......@@ -184,20 +322,6 @@ impl MuType {
_ => None
}
}
pub fn is_float(&self) -> bool {
match self.v {
MuType_::Float => true,
_ => false
}
}
pub fn is_double(&self) -> bool {
match self.v {
MuType_::Double => true,
_ => false
}
}
}
pub type StructTag = MuName;
......@@ -484,131 +608,6 @@ impl MuType_ {
}
}
/// is a type floating-point type?
pub fn is_fp(ty: &MuType) -> bool {
match ty.v {
MuType_::Float | MuType_::Double => true,
_ => false
}
}
/// is a type raw pointer?
pub fn is_ptr(ty: &MuType) -> bool {
match ty.v {
MuType_::UPtr(_) | MuType_::UFuncPtr(_) => true,
_ => false
}
}
/// this a type reference type (located in heap)?
pub fn is_reference(ty: &MuType) -> bool {
match ty.v {
MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_) => true,
_ => false
}
}
/// this is a aggregated type (consited of other types)
pub fn is_aggregate(ty: &MuType) -> bool {
match ty.v {
MuType_::Struct(_)
| MuType_::Hybrid(_)
| MuType_::Array(_, _) => true,
_ => false
}
}
/// is a type scalar type?
pub fn is_scalar(ty: &MuType) -> bool {
match ty.v {
MuType_::Int(_)
| MuType_::Float
| MuType_::Double
| MuType_::Ref(_)
| MuType_::IRef(_)
| MuType_::WeakRef(_)
| MuType_::FuncRef(_)
| MuType_::UFuncPtr(_)
| MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64
| MuType_::UPtr(_) => true,
_ => false
}
}
/// is a type traced by the garbage collector?
/// Note: An aggregated type is traced if any of its part is traced.
pub fn is_traced(ty: &MuType) -> bool {
match ty.v {
MuType_::Ref(_) => true,
MuType_::IRef(_) => true,
MuType_::WeakRef(_) => true,
MuType_::Array(ref elem_ty, _)
| MuType_::Vector(ref elem_ty, _) => is_traced(elem_ty),
MuType_::ThreadRef
| MuType_::StackRef
| MuType_::Tagref64 => true,
MuType_::Hybrid(ref tag) => {
let map = HYBRID_TAG_MAP.read().unwrap();
let hybrid_ty = map.get(tag).unwrap();
let ref fix_tys = hybrid_ty.fix_tys;
let ref var_ty = hybrid_ty.var_ty;
is_traced(var_ty) ||
fix_tys.into_iter().map(|ty| is_traced(ty))
.fold(false, |ret, this| ret || this)
},
MuType_::Struct(ref tag) => {
let map = STRUCT_TAG_MAP.read().unwrap();
let struct_ty = map.get(tag).unwrap();
let ref field_tys = struct_ty.tys;
field_tys.into_iter().map(|ty| is_traced(&ty))
.fold(false, |ret, this| ret || this)
},
_ => false
}
}
/// is a type native safe?
/// Note: An aggregated type is native safe if all of its parts are native safe.
pub fn is_native_safe(ty: &MuType) -> bool {
match ty.v {
MuType_::Int(_) => true,
MuType_::Float => true,
MuType_::Double => true,
MuType_::Void => true,
MuType_::Array(ref elem_ty, _)
| MuType_::Vector(ref elem_ty, _) => is_native_safe(elem_ty),
MuType_::UPtr(_) => true,
MuType_::UFuncPtr(_) => true,
MuType_::Hybrid(ref tag) => {
let map = HYBRID_TAG_MAP.read().unwrap();
let hybrid_ty = map.get(tag).unwrap();
let ref fix_tys = hybrid_ty.fix_tys;
let ref var_ty = hybrid_ty.var_ty;
is_native_safe(var_ty) &&
fix_tys.into_iter().map(|ty| is_native_safe(&ty))
.fold(true, |ret, this| ret && this)
},
MuType_::Struct(ref tag) => {
let map = STRUCT_TAG_MAP.read().unwrap();
let struct_ty = map.get(tag).unwrap();
let ref field_tys = struct_ty.tys;
field_tys.into_iter().map(|ty| is_native_safe(&ty))
.fold(true, |ret, this| ret && this)
},
_ => false
}
}
pub fn get_referent_ty(ty: &MuType) -> Option<P<MuType>> {
match ty.v {
MuType_::Ref(ref referent)
......
......@@ -19,7 +19,6 @@ use utils::LinkedHashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types::*;
use std::str;
use std::usize;
......@@ -3637,10 +3636,12 @@ pub fn spill_rewrite(
let mut codegen = ASMCodeGen::new();
codegen.start_code_sequence();
if is_fp(&temp_ty) {
if RegGroup::get_from_ty(&temp_ty) == RegGroup::FPR {
codegen.emit_spill_load_fpr(&temp, spill_mem);
} else {
} else if RegGroup::get_from_ty(&temp_ty) == RegGroup::GPR {
codegen.emit_spill_load_gpr(&temp, spill_mem);
} else {
unimplemented!()
}
codegen.finish_code_sequence_asm()
......@@ -3686,10 +3687,12 @@ pub fn spill_rewrite(
let mut codegen = ASMCodeGen::new();
codegen.start_code_sequence();
if is_fp(&temp.ty) {
if RegGroup::get_from_ty(&temp.ty) == RegGroup::FPR {
codegen.emit_spill_store_fpr(spill_mem, &temp);
} else {
} else if RegGroup::get_from_ty(&temp.ty) == RegGroup::GPR {
codegen.emit_spill_store_gpr(spill_mem, &temp);
} else {
unimplemented!()
}
codegen.finish_code_sequence_asm()
......
......@@ -3,7 +3,6 @@ pub mod reg_alloc;
pub mod peephole_opt;
pub mod code_emission;
use ast::types;
use utils::ByteSize;
use utils::math::align_up;
use runtime::mm;
......@@ -224,13 +223,13 @@ fn layout_struct(tys: &Vec<P<MuType>>, vm: &VM) -> BackendTypeInfo {
// for convenience, if the struct contains other struct/array
// we do not use reference map
if types::is_aggregate(ty) {
if ty.is_aggregate() {
use_ref_offsets = false;
}
// if this type is reference type, we store its offsets
// we may not use this ref map though
if types::is_reference(ty) {
if ty.is_reference() {
ref_offsets.push(cur);
}
// always store its gc type (we may not use it as well)
......
......@@ -126,65 +126,65 @@ fn test_cyclic_struct() {
fn test_is_traced() {
let types = create_types();
assert_eq!(is_traced(&types[0]), false);
assert_eq!(is_traced(&types[1]), false);
assert_eq!(is_traced(&types[2]), false);
assert_eq!(is_traced(&types[3]), true);
assert_eq!(is_traced(&types[4]), true);
assert_eq!(is_traced(&types[5]), true);
assert_eq!(is_traced(&types[6]), false);
assert_eq!(is_traced(&types[7]), false);
assert_eq!(types[0].is_traced(), false);
assert_eq!(types[1].is_traced(), false);
assert_eq!(types[2].is_traced(), false);
assert_eq!(types[3].is_traced(), true);
assert_eq!(types[4].is_traced(), true);
assert_eq!(types[5].is_traced(), true);
assert_eq!(types[6].is_traced(), false);
assert_eq!(types[7].is_traced(), false);
let struct3 = MuType::new(100, MuType_::mustruct("MyStructTag3".to_string(), vec![types[3].clone(), types[0].clone()]));
assert_eq!(is_traced(&struct3), true);
assert_eq!(struct3.is_traced(), true);
let struct4 = MuType::new(101, MuType_::mustruct("MyStructTag4".to_string(), vec![types[3].clone(), types[4].clone()]));
assert_eq!(is_traced(&struct4), true);
assert_eq!(is_traced(&types[8]), false);
assert_eq!(struct4.is_traced(), true);
assert_eq!(types[8].is_traced(), false);
let ref_array = MuType::new(102, MuType_::array(types[3].clone(), 5));
assert_eq!(is_traced(&ref_array), true);
assert_eq!(is_traced(&types[9]), false);
assert_eq!(ref_array.is_traced(), true);
assert_eq!(types[9].is_traced(), false);
let fix_ref_hybrid = MuType::new(103, MuType_::hybrid("FixRefHybrid".to_string(), vec![types[3].clone(), types[0].clone()], types[0].clone()));
assert_eq!(is_traced(&fix_ref_hybrid), true);
assert_eq!(fix_ref_hybrid.is_traced(), true);
let var_ref_hybrid = MuType::new(104, MuType_::hybrid("VarRefHybrid".to_string(), vec![types[0].clone(), types[1].clone()], types[3].clone()));
assert_eq!(is_traced(&var_ref_hybrid), true);
assert_eq!(is_traced(&types[10]), false);
assert_eq!(is_traced(&types[11]), true);
assert_eq!(is_traced(&types[12]), true);
assert_eq!(is_traced(&types[13]), true);
assert_eq!(is_traced(&types[14]), false);
assert_eq!(is_traced(&types[15]), false);
assert_eq!(is_traced(&types[16]), false);
assert_eq!(var_ref_hybrid.is_traced(), true);
assert_eq!(types[10].is_traced(), false);
assert_eq!(types[11].is_traced(), true);
assert_eq!(types[12].is_traced(), true);
assert_eq!(types[13].is_traced(), true);
assert_eq!(types[14].is_traced(), false);
assert_eq!(types[15].is_traced(), false);
assert_eq!(types[16].is_traced(), false);
}
#[test]
fn test_is_native_safe() {
let types = create_types();
assert_eq!(is_native_safe(&types[0]), true);
assert_eq!(is_native_safe(&types[1]), true);
assert_eq!(is_native_safe(&types[2]), true);
assert_eq!(is_native_safe(&types[3]), false);
assert_eq!(is_native_safe(&types[4]), false);
assert_eq!(is_native_safe(&types[5]), false);
assert_eq!(is_native_safe(&types[6]), true);
assert_eq!(is_native_safe(&types[7]), true);
assert_eq!(types[0].is_native_safe(), true);
assert_eq!(types[1].is_native_safe(), true);
assert_eq!(types[2].is_native_safe(), true);
assert_eq!(types[3].is_native_safe(), false);
assert_eq!(types[4].is_native_safe(), false);
assert_eq!(types[5].is_native_safe(), false);
assert_eq!(types[6].is_native_safe(), true);
assert_eq!(types[7].is_native_safe(), true);
let struct3 = MuType::new(100, MuType_::mustruct("MyStructTag3".to_string(), vec![types[3].clone(), types[0].clone()]));
assert_eq!(is_native_safe(&struct3), false);
assert_eq!(struct3.is_native_safe(), false);
let struct4 = MuType::new(101, MuType_::mustruct("MyStructTag4".to_string(), vec![types[3].clone(), types[4].clone()]));
assert_eq!(is_native_safe(&struct4), false);
assert_eq!(is_native_safe(&types[8]), true);
assert_eq!(struct4.is_native_safe(), false);
assert_eq!(types[8].is_native_safe(), true);
let ref_array = MuType::new(102, MuType_::array(types[3].clone(), 5));
assert_eq!(is_native_safe(&ref_array), false);
assert_eq!(is_native_safe(&types[9]), true);
assert_eq!(ref_array.is_native_safe(), false);
assert_eq!(types[9].is_native_safe(), true);
let fix_ref_hybrid = MuType::new(103, MuType_::hybrid("FixRefHybrid".to_string(), vec![types[3].clone(), types[0].clone()], types[0].clone()));
assert_eq!(is_native_safe(&fix_ref_hybrid), false);
assert_eq!(fix_ref_hybrid.is_native_safe(), false);
let var_ref_hybrid = MuType::new(104, MuType_::hybrid("VarRefHybrid".to_string(), vec![types[0].clone(), types[1].clone()], types[3].clone()));
assert_eq!(is_native_safe(&var_ref_hybrid), false);
assert_eq!(is_native_safe(&types[10]), true);
assert_eq!(is_native_safe(&types[11]), false);
assert_eq!(is_native_safe(&types[12]), false);
assert_eq!(is_native_safe(&types[13]), false);
assert_eq!(is_native_safe(&types[14]), true);
assert_eq!(is_native_safe(&types[15]), false); // funcref is not native safe
assert_eq!(var_ref_hybrid.is_native_safe(), false);
assert_eq!(types[10].is_native_safe(), true);
assert_eq!(types[11].is_native_safe(), false);
assert_eq!(types[12].is_native_safe(), false);
assert_eq!(types[13].is_native_safe(), false);
assert_eq!(types[14].is_native_safe(), true);
assert_eq!(types[15].is_native_safe(), false); // funcref is not native safe
// and not traced either
assert_eq!(is_native_safe(&types[16]), true);
assert_eq!(types[16].is_native_safe(), true);
}
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