Commit d3c8e060 authored by qinsoon's avatar qinsoon

[wip] use String for MuName. Impl Serializable

parent df5ad396
......@@ -20,4 +20,4 @@ linked-hash-map = "0.0.10"
hprof = "0.1.3"
memmap = "0.4.0"
memsec = "0.1.9"
rustc-serialize = "0.3"
\ No newline at end of file
rustc-serialize = "*"
\ No newline at end of file
......@@ -15,7 +15,7 @@ use utils::Address;
pub type WPID = usize;
pub type MuID = usize;
pub type MuName = &'static str;
pub type MuName = String;
pub type OpIndex = usize;
......@@ -123,8 +123,8 @@ impl MuFunctionVersion {
}
pub fn new_ssa(&mut self, id: MuID, tag: MuName, ty: P<MuType>) -> P<TreeNode> {
self.context.value_tags.insert(tag, id);
self.context.values.insert(id, SSAVarEntry{id: id, name: Some(tag), ty: ty.clone(), use_count: Cell::new(0), expr: None});
self.context.value_tags.insert(tag.clone(), id);
self.context.values.insert(id, SSAVarEntry{id: id, name: Some(tag.clone()), ty: ty.clone(), use_count: Cell::new(0), expr: None});
P(TreeNode {
hdr: MuEntityHeader::unnamed(id),
......@@ -209,15 +209,15 @@ impl FunctionContext {
}
}
pub fn get_value_by_tag(&self, tag: MuName) -> Option<&SSAVarEntry> {
match self.value_tags.get(tag) {
pub fn get_value_by_tag(&self, tag: &str) -> Option<&SSAVarEntry> {
match self.value_tags.get(&tag.to_string()) {
Some(id) => self.get_value(*id),
None => None
}
}
pub fn get_value_mut_by_tag(&mut self, tag: MuName) -> Option<&mut SSAVarEntry> {
let id : MuID = match self.value_tags.get(tag) {
pub fn get_value_mut_by_tag(&mut self, tag: &str) -> Option<&mut SSAVarEntry> {
let id : MuID = match self.value_tags.get(&tag.to_string()) {
Some(id) => *id,
None => return None
};
......@@ -559,7 +559,7 @@ impl SSAVarEntry {
impl fmt::Display for SSAVarEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.name.is_some() {
write!(f, "{} {}#{}", self.ty, self.name.unwrap(), self.id)
write!(f, "{} {}#{}", self.ty, self.name.as_ref().unwrap(), self.id)
} else {
write!(f, "{} {}#{}", self.ty, "???", self.id)
}
......@@ -637,6 +637,34 @@ pub struct MuEntityHeader {
pub name: RwLock<Option<MuName>>
}
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for MuEntityHeader {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("MuEntityHeader", 2, |s| {
try!(s.emit_struct_field("id", 0, |s| self.id.encode(s)));
let name = &self.name.read().unwrap();
try!(s.emit_struct_field("name", 1, |s| name.encode(s)));
Ok(())
})
}
}
impl Decodable for MuEntityHeader {
fn decode<D: Decoder>(d: &mut D) -> Result<MuEntityHeader, D::Error> {
d.read_struct("MuEntityHeader", 2, |d| {
let id = try!(d.read_struct_field("id", 0, |d| {d.read_usize()}));
let name = try!(d.read_struct_field("name", 1, |d| Decodable::decode(d)));
Ok(MuEntityHeader{
id: id,
name: RwLock::new(name)
})
})
}
}
impl MuEntityHeader {
pub fn unnamed(id: MuID) -> MuEntityHeader {
MuEntityHeader {
......@@ -657,7 +685,7 @@ impl MuEntityHeader {
}
pub fn name(&self) -> Option<MuName> {
*self.name.read().unwrap()
self.name.read().unwrap().clone()
}
}
......
......@@ -6,6 +6,8 @@ use std::fmt;
use std::collections::HashMap;
use std::sync::RwLock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(PartialEq, Debug)]
pub struct MuType {
pub hdr: MuEntityHeader,
......@@ -21,6 +23,16 @@ impl MuType {
}
}
//impl Encodable for MuType {
// fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// //serialize 2 fields
// s.emit_struct("MuType", 2, |s| {
// // hdr
// try!(s.emit_struct_field("hdr", 0, |s| hdr.encode(s)));
// })
// }
//}
#[derive(PartialEq, Debug)]
pub enum MuType_ {
/// int <length>
......@@ -95,7 +107,7 @@ impl fmt::Display for MuType_ {
&MuType_::Vector(ref ty, size) => write!(f, "vector<{} {}>", ty, size),
&MuType_::FuncRef(ref sig) => write!(f, "funcref<{}>", sig),
&MuType_::UFuncPtr(ref sig) => write!(f, "ufuncref<{}>", sig),
&MuType_::Struct(tag) => write!(f, "{}(struct)", tag)
&MuType_::Struct(ref tag) => write!(f, "{}(struct)", tag)
}
}
}
......@@ -159,7 +171,7 @@ impl MuType_ {
}
pub fn mustruct_empty(tag: MuName) -> MuType_ {
let struct_ty_ = StructType_{tys: vec![]};
STRUCT_TAG_MAP.write().unwrap().insert(tag, struct_ty_);
STRUCT_TAG_MAP.write().unwrap().insert(tag.clone(), struct_ty_);
MuType_::Struct(tag)
}
......@@ -168,7 +180,7 @@ impl MuType_ {
// if there is an attempt to use a same tag for different struct,
// we panic
match STRUCT_TAG_MAP.read().unwrap().get(tag) {
match STRUCT_TAG_MAP.read().unwrap().get(&tag) {
Some(old_struct_ty_) => {
if struct_ty_ != *old_struct_ty_ {
panic!(format!(
......@@ -179,7 +191,7 @@ impl MuType_ {
None => {}
}
// otherwise, store the tag
STRUCT_TAG_MAP.write().unwrap().insert(tag, struct_ty_);
STRUCT_TAG_MAP.write().unwrap().insert(tag.clone(), struct_ty_);
MuType_::Struct(tag)
}
......@@ -264,7 +276,7 @@ pub fn is_traced(ty: &MuType) -> bool {
fix_tys.into_iter().map(|ty| is_traced(ty))
.fold(false, |ret, this| ret || this)
},
MuType_::Struct(tag) => {
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;
......@@ -293,7 +305,7 @@ pub fn is_native_safe(ty: &MuType) -> bool {
fix_tys.into_iter().map(|ty| is_native_safe(&ty))
.fold(true, |ret, this| ret && this)
},
MuType_::Struct(tag) => {
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;
......
......@@ -80,7 +80,7 @@ impl MachineCode for ASMCode {
fn replace_reg(&mut self, from: MuID, to: MuID) {
let to_reg_tag : MuName = backend::all_regs().get(&to).unwrap().name().unwrap();
let to_reg_string = "%".to_string() + to_reg_tag;
let to_reg_string = "%".to_string() + &to_reg_tag;
match self.reg_defines.get(&from) {
Some(defines) => {
......@@ -142,20 +142,20 @@ impl MachineCode for ASMCode {
self.preds[i], self.succs[i]);
}
fn get_ir_block_livein(&self, block: MuName) -> Option<&Vec<MuID>> {
self.block_livein.get(&block)
fn get_ir_block_livein(&self, block: &str) -> Option<&Vec<MuID>> {
self.block_livein.get(&block.to_string())
}
fn get_ir_block_liveout(&self, block: MuName) -> Option<&Vec<MuID>> {
self.block_liveout.get(&block)
fn get_ir_block_liveout(&self, block: &str) -> Option<&Vec<MuID>> {
self.block_liveout.get(&block.to_string())
}
fn get_all_blocks(&self) -> &Vec<MuName> {
&self.blocks
}
fn get_block_range(&self, block: MuName) -> Option<ops::Range<usize>> {
match self.block_range.get(&block) {
fn get_block_range(&self, block: &str) -> Option<ops::Range<usize>> {
match self.block_range.get(&block.to_string()) {
Some(r) => Some(r.clone()),
None => None
}
......@@ -252,11 +252,11 @@ impl ASMCodeGen {
self.cur().code.len()
}
fn add_asm_block_label(&mut self, code: String, block_name: &'static str) {
fn add_asm_block_label(&mut self, code: String, block_name: MuName) {
let l = self.line();
self.cur_mut().code.push(ASM::symbolic(code));
self.cur_mut().idx_to_blk.insert(l, block_name);
self.cur_mut().idx_to_blk.insert(l, block_name.clone());
self.cur_mut().blk_to_idx.insert(block_name, l);
}
......@@ -285,14 +285,14 @@ impl ASMCodeGen {
self.add_asm_inst(code, vec![], vec![], uses, vec![], false);
}
fn add_asm_branch(&mut self, code: String, target: &'static str) {
fn add_asm_branch(&mut self, code: String, target: MuName) {
let l = self.line();
self.cur_mut().branches.insert(l, target);
self.add_asm_inst(code, vec![], vec![], vec![], vec![], false);
}
fn add_asm_branch2(&mut self, code: String, target: &'static str) {
fn add_asm_branch2(&mut self, code: String, target: MuName) {
let l = self.line();
self.cur_mut().cond_branches.insert(l, target);
......@@ -472,8 +472,8 @@ impl ASMCodeGen {
result_str.push(')');
loc_cursor += 1;
},
Value_::Memory(MemoryLocation::Symbolic{ref base, label}) => {
result_str.push_str(&symbol(label));
Value_::Memory(MemoryLocation::Symbolic{ref base, ref label}) => {
result_str.push_str(&symbol(label.clone()));
loc_cursor += label.len();
if base.is_some() {
......@@ -508,7 +508,7 @@ impl ASMCodeGen {
}
fn asm_block_label(&self, label: MuName) -> String {
symbol(&format!("{}_{}", self.cur().name, label))
symbol(format!("{}_{}", self.cur().name, label))
}
fn control_flow_analysis(&mut self) {
......@@ -579,7 +579,7 @@ impl ASMCodeGen {
impl CodeGenerator for ASMCodeGen {
fn start_code(&mut self, func_name: MuName) {
self.cur = Some(Box::new(ASMCode {
name: func_name,
name: func_name.clone(),
code: vec![],
reg_defines: HashMap::new(),
reg_uses: HashMap::new(),
......@@ -603,8 +603,8 @@ impl CodeGenerator for ASMCodeGen {
}));
// to link with C sources via gcc
self.add_asm_symbolic(directive_globl(symbol(func_name)));
self.add_asm_symbolic(format!("{}:", symbol(func_name)));
self.add_asm_symbolic(directive_globl(symbol(func_name.clone())));
self.add_asm_symbolic(format!("{}:", symbol(func_name.clone())));
}
fn finish_code(&mut self) -> Box<MachineCode> {
......@@ -632,9 +632,9 @@ impl CodeGenerator for ASMCodeGen {
}
fn start_block(&mut self, block_name: MuName) {
let label = format!("{}:", self.asm_block_label(block_name));
self.add_asm_block_label(label, block_name);
self.cur_mut().blocks.push(block_name);
let label = format!("{}:", self.asm_block_label(block_name.clone()));
self.add_asm_block_label(label, block_name.clone());
self.cur_mut().blocks.push(block_name.clone());
let start = self.line();
self.cur_mut().block_start.insert(block_name, start);
......@@ -652,7 +652,7 @@ impl CodeGenerator for ASMCodeGen {
let mut res = {
if !cur.block_livein.contains_key(&block_name) {
cur.block_livein.insert(block_name, vec![]);
cur.block_livein.insert(block_name.clone(), vec![]);
} else {
panic!("seems we are inserting livein to block {} twice", block_name);
}
......@@ -670,7 +670,7 @@ impl CodeGenerator for ASMCodeGen {
let mut res = {
if !cur.block_liveout.contains_key(&block_name) {
cur.block_liveout.insert(block_name, vec![]);
cur.block_liveout.insert(block_name.clone(), vec![]);
} else {
panic!("seems we are inserting livein to block {} twice", block_name);
}
......@@ -927,7 +927,7 @@ impl CodeGenerator for ASMCodeGen {
trace!("emit: jmp {}", dest_name);
// symbolic label, we dont need to patch it
let asm = format!("jmp {}", self.asm_block_label(dest_name));
let asm = format!("jmp {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch(asm, dest_name)
}
......@@ -935,7 +935,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: je {}", dest_name);
let asm = format!("je {}", self.asm_block_label(dest_name));
let asm = format!("je {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -943,7 +943,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jne {}", dest_name);
let asm = format!("jne {}", self.asm_block_label(dest_name));
let asm = format!("jne {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -951,7 +951,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: ja {}", dest_name);
let asm = format!("ja {}", self.asm_block_label(dest_name));
let asm = format!("ja {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -959,7 +959,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jae {}", dest_name);
let asm = format!("jae {}", self.asm_block_label(dest_name));
let asm = format!("jae {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -967,7 +967,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jb {}", dest_name);
let asm = format!("jb {}", self.asm_block_label(dest_name));
let asm = format!("jb {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -975,7 +975,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jbe {}", dest_name);
let asm = format!("jbe {}", self.asm_block_label(dest_name));
let asm = format!("jbe {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -983,7 +983,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jg {}", dest_name);
let asm = format!("jg {}", self.asm_block_label(dest_name));
let asm = format!("jg {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -991,7 +991,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jge {}", dest_name);
let asm = format!("jge {}", self.asm_block_label(dest_name));
let asm = format!("jge {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -999,7 +999,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jl {}", dest_name);
let asm = format!("jl {}", self.asm_block_label(dest_name));
let asm = format!("jl {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -1007,7 +1007,7 @@ impl CodeGenerator for ASMCodeGen {
let dest_name = dest.name().unwrap();
trace!("emit: jle {}", dest_name);
let asm = format!("jle {}", self.asm_block_label(dest_name));
let asm = format!("jle {}", self.asm_block_label(dest_name.clone()));
self.add_asm_branch2(asm, dest_name);
}
......@@ -1177,11 +1177,11 @@ fn directive_comm(name: String, size: ByteSize, align: ByteSize) -> String {
}
#[cfg(target_os = "linux")]
fn symbol(name: &str) -> String {
name.to_string()
fn symbol(name: String) -> String {
name
}
#[cfg(target_os = "macos")]
fn symbol(name: &str) -> String {
fn symbol(name: String) -> String {
format!("_{}", name)
}
......@@ -455,13 +455,13 @@ impl <'a> InstructionSelection {
}
fn emit_common_prologue(&mut self, args: &Vec<P<Value>>) {
let block_name = "prologue";
self.backend.start_block(block_name);
let block_name = "prologue".to_string();
self.backend.start_block(block_name.clone());
// no livein
// liveout = entry block's args
self.backend.set_block_livein(block_name, &vec![]);
self.backend.set_block_liveout(block_name, args);
self.backend.set_block_livein(block_name.clone(), &vec![]);
self.backend.set_block_liveout(block_name.clone(), args);
// push rbp
self.backend.emit_push_r64(&x86_64::RBP);
......@@ -805,16 +805,16 @@ impl CompilerPass for InstructionSelection {
let block = func.content.as_ref().unwrap().get_block(*block_id);
let block_label = block.name().unwrap();
self.backend.start_block(block_label);
self.backend.start_block(block_label.clone());
let block_content = block.content.as_ref().unwrap();
// live in is args of the block
self.backend.set_block_livein(block_label, &block_content.args);
self.backend.set_block_livein(block_label.clone(), &block_content.args);
// live out is the union of all branch args of this block
let live_out = block_content.get_out_arguments();
self.backend.set_block_liveout(block_label, &live_out);
self.backend.set_block_liveout(block_label.clone(), &live_out);
for inst in block_content.body.iter() {
self.instruction_select(inst, func, vm);
......
......@@ -23,7 +23,7 @@ macro_rules! GPR {
{
let id = new_machine_id();
P(Value {
hdr: MuEntityHeader::named(id, $name),
hdr: MuEntityHeader::named(id, $name.to_string()),
ty: GPR_TY.clone(),
v: Value_::SSAVar(id)
})
......@@ -36,7 +36,7 @@ macro_rules! FPR {
{
let id = new_machine_id();
P(Value {
hdr: MuEntityHeader::named(id, $name),
hdr: MuEntityHeader::named(id, $name.to_string()),
ty: FPR_TY.clone(),
v: Value_::SSAVar(id)
})
......
......@@ -78,7 +78,7 @@ pub fn resolve_backend_type_info (ty: &MuType, vm: &VM) -> BackendTypeInfo {
BackendTypeInfo{size: ele_ty.size * len, alignment: ele_ty.alignment, struct_layout: None}
}
// struct
MuType_::Struct(name) => {
MuType_::Struct(ref name) => {
let read_lock = STRUCT_TAG_MAP.read().unwrap();
let struc = read_lock.get(name).unwrap();
let tys = struc.get_tys();
......
......@@ -289,12 +289,12 @@ pub fn build_chaitin_briggs (cf: &CompiledFunction, func: &MuFunctionVersion) ->
for block in cf.mc.get_all_blocks() {
// Current_Live(B) = LiveOut(B)
let mut current_live = LinkedHashSet::from_vec(match cf.mc.get_ir_block_liveout(block) {
let mut current_live = LinkedHashSet::from_vec(match cf.mc.get_ir_block_liveout(&block) {
Some(liveout) => liveout.to_vec(),
None => panic!("cannot find liveout for block {}", block)
});
let range = cf.mc.get_block_range(block);
let range = cf.mc.get_block_range(&block);
if range.is_none() {
continue;
}
......
......@@ -3,6 +3,7 @@ extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate immix_rust as gc;
extern crate rustc_serialize;
#[macro_use]
pub mod utils;
......
......@@ -9,7 +9,7 @@ use ast::ir::*;
use compiler::backend::Word;
use compiler::backend::RegGroup;
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Debug)]
pub enum ValueLocation {
Register(RegGroup, MuID),
Direct(RegGroup, Address),
......
......@@ -62,12 +62,12 @@ impl MuVM {
Box::into_raw(ctx)
}
pub fn id_of(&self, name: MuName) -> MuID {
self.internal.get_id_of(name)
pub fn id_of(&self, name: &str) -> MuID {
self.internal.id_of(name)
}
pub fn name_of(&self, id: MuID) -> MuName {
self.internal.get_name_of(id)
self.internal.name_of(id)
}
}
......@@ -236,12 +236,12 @@ struct MuCtxInternal {
}
impl MuCtx {
pub fn id_of(&self, name: MuName) -> MuID {
self.internal.vm.get_id_of(name)
pub fn id_of(&self, name: &str) -> MuID {
self.internal.vm.id_of(name)
}
pub fn name_of(&self, id: MuID) -> MuName {
self.internal.vm.get_name_of(id)
self.internal.vm.name_of(id)
}
pub fn close_context(ctx: *mut MuCtx) {
......
......@@ -26,11 +26,11 @@ pub trait MachineCode {
fn get_inst_reg_uses(&self, index: usize) -> &Vec<MuID>;
fn get_inst_reg_defines(&self, index: usize) -> &Vec<MuID>;
fn get_ir_block_livein(&self, block: MuName) -> Option<&Vec<MuID>>;
fn get_ir_block_liveout(&self, block: MuName) -> Option<&Vec<MuID>>;
fn get_ir_block_livein(&self, block: &str) -> Option<&Vec<MuID>>;
fn get_ir_block_liveout(&self, block: &str) -> Option<&Vec<MuID>>;
fn get_all_blocks(&self) -> &Vec<MuName>;
fn get_block_range(&self, block: MuName) -> Option<ops::Range<usize>>;
fn get_block_range(&self, block: &str) -> Option<ops::Range<usize>>;
fn replace_reg(&mut self, from: MuID, to: MuID);
fn set_inst_nop(&mut self, index: usize);
......
......@@ -12,32 +12,76 @@ use runtime::thread::*;
use runtime::ValueLocation;
use utils::Address;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::RwLock;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering};
use std::thread::JoinHandle;
pub struct VM {
// serialize
// 1
next_id: AtomicUsize,
is_running: AtomicBool,
// 2
id_name_map: RwLock<HashMap<MuID, MuName>>,
// 3
name_id_map: RwLock<HashMap<MuName, MuID>>,
// 4
types: RwLock<HashMap<MuID, P<MuType>>>,
// 5
backend_type_info: RwLock<HashMap<MuID, P<BackendTypeInfo>>>,
// 6
constants: RwLock<HashMap<MuID, P<Value>>>,
// 7
globals: RwLock<HashMap<MuID, P<Value>>>,
// 8
func_sigs: RwLock<HashMap<MuID, P<MuFuncSig>>>,
// 9
// key: (func_id, func_ver_id)
func_vers: RwLock<HashMap<(MuID, MuID), RwLock<MuFunctionVersion>>>,
funcs: RwLock<HashMap<MuID, RwLock<MuFunction>>>,
// 10
pub primordial: RwLock<Option<MuPrimordialThread>>,
compiled_funcs: RwLock<HashMap<MuID, RwLock<CompiledFunction>>>,
// partially serialize
// 11
func_vers: RwLock<HashMap<(MuID, MuID), RwLock<MuFunctionVersion>>>,
// 12
compiled_funcs: RwLock<HashMap<MuID, RwLock<CompiledFunction>>>,
// no serialize
is_running: AtomicBool,
threads: RwLock<Vec<JoinHandle<()>>>,
pub primordial: RwLock<Option<MuPrimordialThread>>
}
impl Encodable for VM {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// serialize 12 fields
s.emit_struct("VM", 12, |s| {
// next_id
try!(s.emit_struct_field("next_id", 0, |s| {
s.emit_usize(self.next_id.load(Ordering::SeqCst))
}));
// id_name_map
{
let map : &HashMap<MuID, MuName> = &self.id_name_map.read().unwrap();
try!(s.emit_struct_field("id_name_map", 1, |s| map.encode(s)));
}
// name_id_map
{
let map : &HashMap<MuName, MuID> = &self.name_id_map.read().unwrap();
try!(s.emit_struct_field("name_id_map", 2, |s| map.encode(s)));
}
// types
{
let types = &self.types.read().unwrap();
}
Ok(())
})
}
}
impl <'a> VM {
......@@ -88,23 +132,23 @@ impl <'a> VM {
pub fn set_name(&self, entity: &MuEntity, name: MuName) {
let id = entity.id();
entity.set_name(name);
entity.set_name(name.clone());
let mut map = self.id_name_map.write().unwrap();
map.insert(id, name);
map.insert(id, name.clone());
let mut map2 = self.name_id_map.write().unwrap();
map2.insert(name, id);
}
pub fn id_of(&self, name: MuName) -> MuID {
pub fn id_of(&self, name: &str) -> MuID {
let map = self.name_id_map.read().unwrap();
*map.get(name).unwrap()
*map.get(&name.to_string()).unwrap()
}
pub fn name_of(&self, id: MuID) -> MuName {
let map = self.id_name_map.read().unwrap();
map.get(&id).unwrap()
map.get(&id).unwrap().clone()
}
pub fn declare_const(&self, id: MuID, ty: P<MuType>, val: Constant) -> P<Value> {
......@@ -208,14 +252,6 @@ impl <'a> VM {
resolved
}
pub fn get_id_of(&self, name: MuName) -> MuID {
*self.name_id_map.read().unwrap().get(&name).unwrap()
}
pub fn get_name_of(&self, id: MuID) -> MuName {
*self.id_name_map.read().unwrap().get(&id).unwrap()
}
pub fn globals(&self) -> &RwLock<HashMap<MuID, P<Value>>> {
&self.globals
}
......
extern crate mu;
extern crate log;
extern crate simple_logger;
mod test_ir;
mod test_compiler;