Commit 3b88ae36 authored by qinsoon's avatar qinsoon

remove RwLock on MuEntityHeader.name (Issue#15), rewrite all tests in Rust with

macro.
parent 2026c567
...@@ -9,7 +9,6 @@ use utils::LinkedHashSet; ...@@ -9,7 +9,6 @@ use utils::LinkedHashSet;
use std::fmt; use std::fmt;
use std::default; use std::default;
use std::sync::RwLock;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
pub type WPID = usize; pub type WPID = usize;
...@@ -74,9 +73,9 @@ pub struct MuFunction { ...@@ -74,9 +73,9 @@ pub struct MuFunction {
} }
impl MuFunction { impl MuFunction {
pub fn new(id: MuID, sig: P<MuFuncSig>) -> MuFunction { pub fn new(entity: MuEntityHeader, sig: P<MuFuncSig>) -> MuFunction {
MuFunction { MuFunction {
hdr: MuEntityHeader::unnamed(id), hdr: entity,
sig: sig, sig: sig,
cur_ver: None, cur_ver: None,
all_vers: vec![] all_vers: vec![]
...@@ -143,9 +142,9 @@ impl fmt::Debug for MuFunctionVersion { ...@@ -143,9 +142,9 @@ impl fmt::Debug for MuFunctionVersion {
} }
impl MuFunctionVersion { impl MuFunctionVersion {
pub fn new(id: MuID, func: MuID, sig: P<MuFuncSig>) -> MuFunctionVersion { pub fn new(entity: MuEntityHeader, func: MuID, sig: P<MuFuncSig>) -> MuFunctionVersion {
MuFunctionVersion{ MuFunctionVersion{
hdr: MuEntityHeader::unnamed(id), hdr: entity,
func_id: func, func_id: func,
sig: sig, sig: sig,
orig_content: None, orig_content: None,
...@@ -194,9 +193,10 @@ impl MuFunctionVersion { ...@@ -194,9 +193,10 @@ impl MuFunctionVersion {
self.is_compiled = true; self.is_compiled = true;
} }
pub fn new_ssa(&mut self, id: MuID, ty: P<MuType>) -> P<TreeNode> { pub fn new_ssa(&mut self, entity: MuEntityHeader, ty: P<MuType>) -> P<TreeNode> {
let id = entity.id();
let val = P(Value{ let val = P(Value{
hdr: MuEntityHeader::unnamed(id), hdr: entity,
ty: ty, ty: ty,
v: Value_::SSAVar(id) v: Value_::SSAVar(id)
}); });
...@@ -425,8 +425,8 @@ impl fmt::Debug for Block { ...@@ -425,8 +425,8 @@ impl fmt::Debug for Block {
} }
impl Block { impl Block {
pub fn new(id: MuID) -> Block { pub fn new(entity: MuEntityHeader) -> Block {
Block{hdr: MuEntityHeader::unnamed(id), content: None, control_flow: ControlFlow::default()} Block{hdr: entity, content: None, control_flow: ControlFlow::default()}
} }
pub fn is_receiving_exception_arg(&self) -> bool { pub fn is_receiving_exception_arg(&self) -> bool {
...@@ -1002,14 +1002,14 @@ impl fmt::Display for MemoryLocation { ...@@ -1002,14 +1002,14 @@ impl fmt::Display for MemoryLocation {
#[derive(Debug)] // Display, PartialEq, Clone #[derive(Debug)] // Display, PartialEq, Clone
pub struct MuEntityHeader { pub struct MuEntityHeader {
id: MuID, id: MuID,
name: RwLock<Option<MuName>> name: Option<MuName>
} }
impl Clone for MuEntityHeader { impl Clone for MuEntityHeader {
fn clone(&self) -> Self { fn clone(&self) -> Self {
MuEntityHeader { MuEntityHeader {
id: self.id, id: self.id,
name: RwLock::new(self.name.read().unwrap().clone()) name: self.name.clone()
} }
} }
} }
...@@ -1020,7 +1020,7 @@ impl Encodable for MuEntityHeader { ...@@ -1020,7 +1020,7 @@ impl Encodable for MuEntityHeader {
s.emit_struct("MuEntityHeader", 2, |s| { s.emit_struct("MuEntityHeader", 2, |s| {
try!(s.emit_struct_field("id", 0, |s| self.id.encode(s))); try!(s.emit_struct_field("id", 0, |s| self.id.encode(s)));
let name = &self.name.read().unwrap(); let name = &self.name;
try!(s.emit_struct_field("name", 1, |s| name.encode(s))); try!(s.emit_struct_field("name", 1, |s| name.encode(s)));
Ok(()) Ok(())
...@@ -1036,7 +1036,7 @@ impl Decodable for MuEntityHeader { ...@@ -1036,7 +1036,7 @@ impl Decodable for MuEntityHeader {
Ok(MuEntityHeader{ Ok(MuEntityHeader{
id: id, id: id,
name: RwLock::new(name) name: name
}) })
}) })
} }
...@@ -1058,14 +1058,14 @@ impl MuEntityHeader { ...@@ -1058,14 +1058,14 @@ impl MuEntityHeader {
pub fn unnamed(id: MuID) -> MuEntityHeader { pub fn unnamed(id: MuID) -> MuEntityHeader {
MuEntityHeader { MuEntityHeader {
id: id, id: id,
name: RwLock::new(None) name: None
} }
} }
pub fn named(id: MuID, name: MuName) -> MuEntityHeader { pub fn named(id: MuID, name: MuName) -> MuEntityHeader {
MuEntityHeader { MuEntityHeader {
id: id, id: id,
name: RwLock::new(Some(name_check(name))) name: Some(name_check(name))
} }
} }
...@@ -1074,12 +1074,7 @@ impl MuEntityHeader { ...@@ -1074,12 +1074,7 @@ impl MuEntityHeader {
} }
pub fn name(&self) -> Option<MuName> { pub fn name(&self) -> Option<MuName> {
self.name.read().unwrap().clone() self.name.clone()
}
pub fn set_name(&self, name: MuName) {
let mut name_guard = self.name.write().unwrap();
*name_guard = Some(name_check(name));
} }
fn abbreviate_name(&self) -> Option<MuName> { fn abbreviate_name(&self) -> Option<MuName> {
...@@ -1129,7 +1124,6 @@ impl fmt::Display for MuEntityHeader { ...@@ -1129,7 +1124,6 @@ impl fmt::Display for MuEntityHeader {
pub trait MuEntity { pub trait MuEntity {
fn id(&self) -> MuID; fn id(&self) -> MuID;
fn name(&self) -> Option<MuName>; fn name(&self) -> Option<MuName>;
fn set_name(&self, name: MuName);
fn as_entity(&self) -> &MuEntity; fn as_entity(&self) -> &MuEntity;
} }
...@@ -1155,13 +1149,6 @@ impl MuEntity for TreeNode { ...@@ -1155,13 +1149,6 @@ impl MuEntity for TreeNode {
} }
} }
fn set_name(&self, name: MuName) {
match self.v {
TreeNode_::Instruction(ref inst) => inst.set_name(name),
TreeNode_::Value(ref pv) => pv.set_name(name)
}
}
fn as_entity(&self) -> &MuEntity { fn as_entity(&self) -> &MuEntity {
match self.v { match self.v {
TreeNode_::Instruction(ref inst) => inst.as_entity(), TreeNode_::Instruction(ref inst) => inst.as_entity(),
......
#[macro_use]
extern crate log; extern crate log;
extern crate simple_logger; extern crate simple_logger;
#[macro_use] #[macro_use]
...@@ -14,9 +13,6 @@ macro_rules! impl_mu_entity { ...@@ -14,9 +13,6 @@ macro_rules! impl_mu_entity {
fn id(&self) -> MuID {self.hdr.id()} fn id(&self) -> MuID {self.hdr.id()}
#[inline(always)] #[inline(always)]
fn name(&self) -> Option<MuName> {self.hdr.name()} fn name(&self) -> Option<MuName> {self.hdr.name()}
fn set_name(&self, name: MuName) {
self.hdr.set_name(name);
}
fn as_entity(&self) -> &MuEntity { fn as_entity(&self) -> &MuEntity {
let ref_ty : &$entity = self; let ref_ty : &$entity = self;
ref_ty as &MuEntity ref_ty as &MuEntity
......
...@@ -3555,7 +3555,7 @@ pub fn spill_rewrite( ...@@ -3555,7 +3555,7 @@ pub fn spill_rewrite(
// generate a random new temporary // generate a random new temporary
let temp_ty = val_reg.ty.clone(); let temp_ty = val_reg.ty.clone();
let temp = func.new_ssa(vm.next_id(), temp_ty.clone()).clone_value(); let temp = func.new_ssa(MuEntityHeader::unnamed(vm.next_id()), temp_ty.clone()).clone_value();
// maintain mapping // maintain mapping
trace!("reg {} used in Inst{} is replaced as {}", val_reg, i, temp); trace!("reg {} used in Inst{} is replaced as {}", val_reg, i, temp);
...@@ -3603,7 +3603,7 @@ pub fn spill_rewrite( ...@@ -3603,7 +3603,7 @@ pub fn spill_rewrite(
temp_for_cur_inst.get(&reg).unwrap().clone() temp_for_cur_inst.get(&reg).unwrap().clone()
} else { } else {
let temp_ty = val_reg.ty.clone(); let temp_ty = val_reg.ty.clone();
let temp = func.new_ssa(vm.next_id(), temp_ty.clone()).clone_value(); let temp = func.new_ssa(MuEntityHeader::unnamed(vm.next_id()), temp_ty.clone()).clone_value();
spilled_scratch_temps.insert(temp.id(), reg); spilled_scratch_temps.insert(temp.id(), reg);
......
...@@ -178,11 +178,11 @@ impl CompilerPass for GenMovPhi { ...@@ -178,11 +178,11 @@ impl CompilerPass for GenMovPhi {
// insert new blocks here // insert new blocks here
for block_info in new_blocks_to_insert { for block_info in new_blocks_to_insert {
let block = { let block = {
let mut ret = Block::new(block_info.blk_id);
let target_id = block_info.target; let target_id = block_info.target;
let name = format!("intermediate_block_{}_to_{}", block_info.blk_id, target_id); let name = format!("intermediate_block_{}_to_{}", block_info.blk_id, target_id);
vm.set_name(ret.as_entity(), name);
let mut ret = Block::new(MuEntityHeader::named(block_info.blk_id, name));
vm.set_name(ret.as_entity());
let mut target_block = f_content.get_block_mut(target_id); let mut target_block = f_content.get_block_mut(target_id);
......
...@@ -177,7 +177,10 @@ impl Inlining { ...@@ -177,7 +177,10 @@ impl Inlining {
let old_name = cur_block.name().unwrap(); let old_name = cur_block.name().unwrap();
// start a new block // start a new block
cur_block = Block::new(vm.next_id()); let new_name = format!("{}_cont_after_inline_{}", old_name, inst_id);
trace!("create continue block for EXPRCALL/CCALL: {}", &new_name);
cur_block = Block::new(MuEntityHeader::named(vm.next_id(), new_name));
cur_block.content = Some(BlockContent{ cur_block.content = Some(BlockContent{
args: { args: {
if inst.value.is_none() { if inst.value.is_none() {
...@@ -190,9 +193,7 @@ impl Inlining { ...@@ -190,9 +193,7 @@ impl Inlining {
body: vec![], body: vec![],
keepalives: None keepalives: None
}); });
let new_name = format!("{}_cont_after_inline_{}", old_name, inst_id); vm.set_name(cur_block.as_entity());
trace!("create continue block for EXPRCALL/CCALL: {}", &new_name);
vm.set_name(cur_block.as_entity(), new_name);
// deal with the inlined function // deal with the inlined function
copy_inline_blocks(&mut new_blocks, cur_block.id(), copy_inline_blocks(&mut new_blocks, cur_block.id(),
...@@ -225,8 +226,9 @@ impl Inlining { ...@@ -225,8 +226,9 @@ impl Inlining {
// other than the inlined function returns, we need an intermediate block to pass extra arguments // other than the inlined function returns, we need an intermediate block to pass extra arguments
if resume.normal_dest.args.len() != inlined_fv_guard.sig.ret_tys.len() { if resume.normal_dest.args.len() != inlined_fv_guard.sig.ret_tys.len() {
debug!("need an extra block for passing normal dest arguments"); debug!("need an extra block for passing normal dest arguments");
let mut intermediate_block = Block::new(vm.next_id()); let int_block_name = format!("inline_{}_arg_pass", inst_id);
vm.set_name(intermediate_block.as_entity(), format!("inline_{}_arg_pass", inst_id)); let mut intermediate_block = Block::new(MuEntityHeader::named(vm.next_id(), int_block_name));
vm.set_name(intermediate_block.as_entity());
// branch to normal_dest with normal_dest arguments // branch to normal_dest with normal_dest arguments
let normal_dest_args = resume.normal_dest.get_arguments_as_node(&ops); let normal_dest_args = resume.normal_dest.get_arguments_as_node(&ops);
......
...@@ -573,9 +573,9 @@ impl <'a> VM { ...@@ -573,9 +573,9 @@ impl <'a> VM {
self.is_running.load(Ordering::Relaxed) self.is_running.load(Ordering::Relaxed)
} }
pub fn set_name(&self, entity: &MuEntity, name: MuName) { pub fn set_name(&self, entity: &MuEntity) {
let id = entity.id(); let id = entity.id();
entity.set_name(name.clone()); let name = entity.name().unwrap();
let mut map = self.id_name_map.write().unwrap(); let mut map = self.id_name_map.write().unwrap();
map.insert(id, name.clone()); map.insert(id, name.clone());
...@@ -601,11 +601,11 @@ impl <'a> VM { ...@@ -601,11 +601,11 @@ impl <'a> VM {
map.get(&id).unwrap().clone() map.get(&id).unwrap().clone()
} }
pub fn declare_const(&self, id: MuID, ty: P<MuType>, val: Constant) -> P<Value> { pub fn declare_const(&self, entity: MuEntityHeader, ty: P<MuType>, val: Constant) -> P<Value> {
let mut constants = self.constants.write().unwrap(); let mut constants = self.constants.write().unwrap();
let ret = P(Value{hdr: MuEntityHeader::unnamed(id), ty: ty, v: Value_::Constant(val)}); let ret = P(Value{hdr: entity, ty: ty, v: Value_::Constant(val)});
self.declare_const_internal(&mut constants, id, ret.clone()); self.declare_const_internal(&mut constants, ret.id(), ret.clone());
ret ret
} }
...@@ -644,17 +644,17 @@ impl <'a> VM { ...@@ -644,17 +644,17 @@ impl <'a> VM {
ValueLocation::Relocatable(backend::RegGroup::GPR, name) ValueLocation::Relocatable(backend::RegGroup::GPR, name)
} }
pub fn declare_global(&self, id: MuID, ty: P<MuType>) -> P<Value> { pub fn declare_global(&self, entity: MuEntityHeader, ty: P<MuType>) -> P<Value> {
let global = P(Value{ let global = P(Value{
hdr: MuEntityHeader::unnamed(id), hdr: entity,
ty: self.declare_type(self.next_id(), MuType_::iref(ty.clone())), ty: self.declare_type(MuEntityHeader::unnamed(self.next_id()), MuType_::iref(ty.clone())),
v: Value_::Global(ty) v: Value_::Global(ty)
}); });
let mut globals = self.globals.write().unwrap(); let mut globals = self.globals.write().unwrap();
let mut global_locs = self.global_locations.write().unwrap(); let mut global_locs = self.global_locations.write().unwrap();
self.declare_global_internal(&mut globals, &mut global_locs, id, global.clone()); self.declare_global_internal(&mut globals, &mut global_locs, global.id(), global.clone());
global global
} }
...@@ -692,12 +692,12 @@ impl <'a> VM { ...@@ -692,12 +692,12 @@ impl <'a> VM {
global_locs.insert(id, loc); global_locs.insert(id, loc);
} }
pub fn declare_type(&self, id: MuID, ty: MuType_) -> P<MuType> { pub fn declare_type(&self, entity: MuEntityHeader, ty: MuType_) -> P<MuType> {
let ty = P(MuType{hdr: MuEntityHeader::unnamed(id), v: ty}); let ty = P(MuType{hdr: entity, v: ty});
let mut types = self.types.write().unwrap(); let mut types = self.types.write().unwrap();
self.declare_type_internal(&mut types, id, ty.clone()); self.declare_type_internal(&mut types, ty.id(), ty.clone());
ty ty
} }
...@@ -729,11 +729,11 @@ impl <'a> VM { ...@@ -729,11 +729,11 @@ impl <'a> VM {
} }
} }
pub fn declare_func_sig(&self, id: MuID, ret_tys: Vec<P<MuType>>, arg_tys: Vec<P<MuType>>) -> P<MuFuncSig> { pub fn declare_func_sig(&self, entity: MuEntityHeader, ret_tys: Vec<P<MuType>>, arg_tys: Vec<P<MuType>>) -> P<MuFuncSig> {
let ret = P(MuFuncSig{hdr: MuEntityHeader::unnamed(id), ret_tys: ret_tys, arg_tys: arg_tys}); let ret = P(MuFuncSig{hdr: entity, ret_tys: ret_tys, arg_tys: arg_tys});
let mut func_sigs = self.func_sigs.write().unwrap(); let mut func_sigs = self.func_sigs.write().unwrap();
self.declare_func_sig_internal(&mut func_sigs, id, ret.clone()); self.declare_func_sig_internal(&mut func_sigs, ret.id(), ret.clone());
ret ret
} }
......
This diff is collapsed.
...@@ -155,112 +155,53 @@ fn test_instruction_new_on_cur_thread() { ...@@ -155,112 +155,53 @@ fn test_instruction_new_on_cur_thread() {
#[allow(unused_variables)] #[allow(unused_variables)]
pub fn alloc_new() -> VM { pub fn alloc_new() -> VM {
let vm = VM::new(); let vm = VM::new();
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) ref_int64 = mu_ref(int64));
typedef! ((vm) iref_int64 = mu_iref(int64));
// .typedef @int64 = int<64> constdef! ((vm) <int64> int64_0 = Constant::Int(0));
// .typedef @iref_int64 = iref<int<64>> constdef! ((vm) <int64> int64_1 = Constant::Int(1));
let type_def_int64 = vm.declare_type(vm.next_id(), MuType_::int(64));
vm.set_name(type_def_int64.as_entity(), "int64".to_string()); funcsig! ((vm) alloc_new_sig = () -> (int64));
let type_def_iref_int64 = vm.declare_type(vm.next_id(), MuType_::iref(type_def_int64.clone())); funcdecl! ((vm) <alloc_new_sig> alloc_new);
vm.set_name(type_def_iref_int64.as_entity(), "iref_int64".to_string()); funcdef! ((vm) <alloc_new_sig> alloc_new VERSION alloc_new_v1);
let type_def_ref_int64 = vm.declare_type(vm.next_id(), MuType_::muref(type_def_int64.clone()));
vm.set_name(type_def_ref_int64.as_entity(), "ref_int64".to_string());
// .const @int_64_0 <@int_64> = 0
// .const @int_64_1 <@int_64> = 1
let const_def_int64_0 = vm.declare_const(vm.next_id(), type_def_int64.clone(), Constant::Int(0));
vm.set_name(const_def_int64_0.as_entity(), "int64_0".to_string());
let const_def_int64_1 = vm.declare_const(vm.next_id(), type_def_int64.clone(), Constant::Int(1));
vm.set_name(const_def_int64_1.as_entity(), "int64_1".to_string());
// .funcsig @alloc_new_sig = () -> (@int64)
let func_sig = vm.declare_func_sig(vm.next_id(), vec![type_def_int64.clone()], vec![]);
vm.set_name(func_sig.as_entity(), "alloc_new_sig".to_string());
// .funcdecl @alloc_new <@alloc_new_sig>
let func = MuFunction::new(vm.next_id(), func_sig.clone());
vm.set_name(func.as_entity(), "alloc_new".to_string());
let func_id = func.id();
vm.declare_func(func);
// .funcdef @alloc VERSION @v1 <@alloc_new_sig>
let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, func_sig.clone());
// %blk_0(): // %blk_0():
let mut blk_0 = Block::new(vm.next_id()); block! ((vm, alloc_new_v1) blk_0);
vm.set_name(blk_0.as_entity(), "blk_0".to_string());
// %a = NEW <@int64_t> // %a = NEW <@int64_t>
let blk_0_a = func_ver.new_ssa(vm.next_id(), type_def_ref_int64.clone()); ssa! ((vm, alloc_new_v1) <ref_int64> blk_0_a);
vm.set_name(blk_0_a.as_entity(), "blk_0_a".to_string()); inst! ((vm, alloc_new_v1) blk_0_new:
let blk_0_inst0 = func_ver.new_inst(Instruction{ blk_0_a = NEW <int64>
hdr: MuEntityHeader::unnamed(vm.next_id()), );
value: Some(vec![blk_0_a.clone_value()]),
ops: RwLock::new(vec![]),
v: Instruction_::New(type_def_int64.clone())
});
// %a_iref = GETIREF <@int_64> @a // %a_iref = GETIREF <@int_64> @a
let blk_0_a_iref = func_ver.new_ssa(vm.next_id(), type_def_iref_int64.clone()); ssa! ((vm, alloc_new_v1) <iref_int64> blk_0_a_iref);
vm.set_name(blk_0_a.as_entity(), "blk_0_a_iref".to_string()); inst! ((vm, alloc_new_v1) blk_0_getiref:
let blk_0_inst1 = func_ver.new_inst(Instruction{ blk_0_a_iref = GETIREF blk_0_a
hdr: MuEntityHeader::unnamed(vm.next_id()), );
value: Some(vec![blk_0_a_iref.clone_value()]),
ops: RwLock::new(vec![blk_0_a.clone()]),
v: Instruction_::GetIRef(0)
});
// STORE <@int_64> @a_iref @int_64_1 // STORE <@int_64> @a_iref @int_64_1
let blk_0_const_int64_1 = func_ver.new_constant(const_def_int64_1.clone()); consta! ((vm, alloc_new_v1) int64_1_local = int64_1);
let blk_0_inst2 = func_ver.new_inst(Instruction{ inst! ((vm, alloc_new_v1) blk_0_store:
hdr: MuEntityHeader::unnamed(vm.next_id()), STORE blk_0_a_iref int64_1_local (is_ptr: false, order: MemoryOrder::Relaxed)
value: None, );
ops: RwLock::new(vec![blk_0_a_iref.clone(), blk_0_const_int64_1.clone()]),
v: Instruction_::Store{ inst! ((vm, alloc_new_v1) blk_0_term:
is_ptr: false, THREADEXIT
order: MemoryOrder::Relaxed, );
mem_loc: 0,
value: 1 define_block!((vm, alloc_new_v1) blk_0() {
} blk_0_new,
}); blk_0_getiref,
blk_0_store,
// // %x = LOAD <@int_64> @a_iref blk_0_term
// let blk_0_x = func_ver.new_ssa(vm.next_id(), type_def_int64.clone()); });
// vm.set_name(blk_0_x.as_entity(), "blk_0_x".to_string());
// let blk_0_inst3 = func_ver.new_inst(vm.next_id(), Instruction{ define_func_ver!((vm) alloc_new_v1 (entry: blk_0) {
// value: Some(vec![blk_0_x.clone_value()]), blk_0
// ops: RwLock::new(vec![blk_0_a_iref.clone()]),
// v: Instruction_::Load{
// is_ptr: false,
// order: MemoryOrder::Relaxed,
// mem_loc: 0
// }
// });
let blk_0_term = func_ver.new_inst(Instruction {
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
ops: RwLock::new(vec![]),
v: Instruction_::ThreadExit
}); });
let blk_0_content = BlockContent {
args: vec![],
exn_arg: None,
body: vec![blk_0_inst0, blk_0_inst1, blk_0_inst2, blk_0_term],
keepalives: None
};
blk_0.content = Some(blk_0_content);
func_ver.define(FunctionContent::new(
blk_0.id(),
{
let mut ret = LinkedHashMap::new();
ret.insert(blk_0.id(), blk_0);
ret
}
));
vm.define_func_version(func_ver);
vm vm
} }
This diff is collapsed.
...@@ -46,105 +46,55 @@ fn test_ccall_exit() { ...@@ -46,105 +46,55 @@ fn test_ccall_exit() {
} }
pub fn gen_ccall_exit(arg: P<TreeNode>, func_ver: &mut MuFunctionVersion, vm: &VM) -> Box<TreeNode> { pub fn gen_ccall_exit(arg: P<TreeNode>, func_ver: &mut MuFunctionVersion, vm: &VM) -> Box<TreeNode> {
// .typedef @int32 = int<32> typedef! ((vm) int32 = mu_int(32));
let type_def_int32 = vm.declare_type(vm.next_id(), MuType_::int(32)); funcsig! ((vm) exit_sig = (int32) -> ());
vm.set_name(type_def_int32.as_entity(), Mu("exit_int32")); typedef! ((vm) ufp_exit = mu_ufuncptr(exit_sig));
// .typedef @exit_sig = (@int32) -> !
let exit_sig = vm.declare_func_sig(vm.next_id(), vec![], vec![type_def_int32.clone()]);
vm.set_name(exit_sig.as_entity(), Mu("exit_sig"));
// .typedef @ufp_exit = ufuncptr(@exit_sig)
let type_def_ufp_exit = vm.declare_type(vm.next_id(), MuType_::UFuncPtr(exit_sig.clone()));
vm.set_name(type_def_ufp_exit.as_entity(), Mu("ufp_exit"));
// .const @exit = EXTERN SYMBOL "exit" // .const @exit = EXTERN SYMBOL "exit"
let const_exit = vm.declare_const(vm.next_id(), type_def_ufp_exit.clone(), Constant::ExternSym(C("exit"))); constdef! ((vm) <ufp_exit> const_exit = Constant::ExternSym(C("exit")));
vm.set_name(const_exit.as_entity(), Mu("exit")); consta! ((vm, func_ver) const_exit_local = const_exit);
// exprCCALL %const_exit (%const_int32_10) inst! ((vm, func_ver) ret:
let const_exit_local = func_ver.new_constant(const_exit.clone()); EXPRCCALL (CallConvention::Foreign(ForeignFFI::C), is_abort: false) const_exit_local (arg)
);
func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()), ret
value: None,
ops: RwLock::new(vec![const_exit_local, arg]),
v: Instruction_::ExprCCall {
data: CallData {
func: 0,
args: vec![1],
convention: CallConvention::Foreign(ForeignFFI::C)
},
is_abort: false
}
})
} }
fn ccall_exit() -> VM { fn ccall_exit() -> VM {
let vm = VM::new(); let vm = VM::new();
// .typedef @int32 = int<32> typedef! ((vm) int32 = mu_int(32));
let type_def_int32 = vm.declare_type(vm.next_id(), MuType_::int(32));
vm.set_name(type_def_int32.as_entity(), Mu("int32"));
// .const @int32_10 = 10
let const_int32_10 = vm.declare_const(vm.next_id(), type_def_int32.clone(), Constant::Int(10));
vm.set_name(const_int32_10.as_entity(), Mu("const_int32_10"));
// .const @int32_0 = 0
let const_int32_0 = vm.declare_const(vm.next_id(), type_def_int32.clone(), Constant::Int(0));
vm.set_name(const_int32_0.as_entity(), Mu("const_int32_0"));
// .funcsig @ccall_exit_sig = () -> ! constdef! ((vm) <int32> int32_10 = Constant::Int(10));
let ccall_exit_sig = vm.declare_func_sig(vm.next_id(), vec![], vec![]); constdef! ((vm) <int32> int32_0 = Constant::Int(0));
vm.set_name(ccall_exit_sig.as_entity(), Mu("ccall_exit_sig"));
// .funcdecl @ccall_exit <@ccall_exit_sig> funcsig! ((vm) ccall_exit_sig = () -> ());
let func_id = vm.next_id(); funcdecl! ((vm) <ccall_exit_sig> ccall_exit);
let func = MuFunction::new(func_id, ccall_exit_sig.clone()); funcdef! ((vm) <ccall_exit_sig> ccall_exit VERSION ccall_exit_v1);
vm.set_name(func.as_entity(), Mu("ccall_exit"));
vm.declare_func(func);
// .funcdef @ccall_exit VERSION @ccall_exit_v1 <@ccall_exit_sig>
let mut func_ver = MuFunctionVersion::new(vm.next_id(), func_id, ccall_exit_sig.clone());
vm.set_name(func_ver.as_entity(), Mu("ccall_exit_v1"));
// %entry(): // %entry():
let mut blk_entry = Block::new(vm.next_id()); block! ((vm, ccall_exit_v1) blk_entry);
vm.set_name(blk_entry.as_entity(), Mu("entry"));
// exprCCALL %const_exit (%const_int32_10) // exprCCALL %const_exit (%const_int32_10)
let const_int32_10_local = func_ver.new_constant(const_int32_10.clone()); consta! ((vm, ccall_exit_v1) int32_10_local = int32_10);
let blk_entry_ccall = gen_ccall_exit(const_int32_10_local.clone(), &mut func_ver, &vm); let blk_entry_ccall = gen_ccall_exit(int32_10_local.clone(), &mut ccall_exit_v1, &vm);
// RET %const_int32_0 // RET %const_int32_0
let const_int32_0_local = func_ver.new_constant(const_int32_0.clone()); consta! ((vm, ccall_exit_v1) int32_0_local = int32_0);