WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 6c505ac1 authored by qinsoon's avatar qinsoon
Browse files

[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