Commit d28af85a authored by qinsoon's avatar qinsoon

serialization

parent d3c8e060
...@@ -6,15 +6,59 @@ use utils::vec_utils::as_str as vector_as_str; ...@@ -6,15 +6,59 @@ use utils::vec_utils::as_str as vector_as_str;
use utils::vec_utils; use utils::vec_utils;
use std::fmt; use std::fmt;
use std::cell::RefCell; use std::sync::RwLock;
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct Instruction { pub struct Instruction {
pub value : Option<Vec<P<Value>>>, pub value : Option<Vec<P<Value>>>,
pub ops : RefCell<Vec<P<TreeNode>>>, pub ops : RwLock<Vec<P<TreeNode>>>,
pub v: Instruction_ pub v: Instruction_
} }
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
impl Encodable for Instruction {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("Instruction", 3, |s| {
try!(s.emit_struct_field("value", 0, |s| self.value.encode(s)));
let ops = &self.ops.read().unwrap();
try!(s.emit_struct_field("ops", 1, |s| ops.encode(s)));
try!(s.emit_struct_field("v", 2, |s| self.v.encode(s)));
Ok(())
})
}
}
impl Decodable for Instruction {
fn decode<D: Decoder>(d: &mut D) -> Result<Instruction, D::Error> {
d.read_struct("Instruction", 3, |d| {
let value = try!(d.read_struct_field("value", 0, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 1, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 2, |d| Decodable::decode(d)));
Ok(Instruction{
value: value,
ops: RwLock::new(ops),
v: v
})
})
}
}
impl Clone for Instruction {
fn clone(&self) -> Self {
Instruction {
value: self.value.clone(),
ops: RwLock::new(self.ops.read().unwrap().clone()),
v: self.v.clone()
}
}
}
impl Instruction { impl Instruction {
fn debug_str(&self, ops: &Vec<P<TreeNode>>) -> String { fn debug_str(&self, ops: &Vec<P<TreeNode>>) -> String {
self.v.debug_str(ops) self.v.debug_str(ops)
...@@ -23,7 +67,7 @@ impl Instruction { ...@@ -23,7 +67,7 @@ impl Instruction {
impl fmt::Display for Instruction { impl fmt::Display for Instruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let ops = &self.ops.borrow(); let ops = &self.ops.read().unwrap();
if self.value.is_some() { if self.value.is_some() {
write!(f, "{} = {}", vector_as_str(self.value.as_ref().unwrap()), self.v.debug_str(ops)) write!(f, "{} = {}", vector_as_str(self.value.as_ref().unwrap()), self.v.debug_str(ops))
} else { } else {
...@@ -32,7 +76,7 @@ impl fmt::Display for Instruction { ...@@ -32,7 +76,7 @@ impl fmt::Display for Instruction {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
pub enum Instruction_ { pub enum Instruction_ {
// non-terminal instruction // non-terminal instruction
...@@ -189,7 +233,7 @@ pub enum Instruction_ { ...@@ -189,7 +233,7 @@ pub enum Instruction_ {
branches: Vec<(OpIndex, Destination)> branches: Vec<(OpIndex, Destination)>
}, },
ExnInstruction{ ExnInstruction{
inner: P<Instruction>, inner: Box<Instruction>,
resume: ResumptionData resume: ResumptionData
} }
} }
...@@ -297,7 +341,7 @@ impl Instruction_ { ...@@ -297,7 +341,7 @@ impl Instruction_ {
} }
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum MemoryOrder { pub enum MemoryOrder {
NotAtomic, NotAtomic,
Relaxed, Relaxed,
...@@ -308,18 +352,18 @@ pub enum MemoryOrder { ...@@ -308,18 +352,18 @@ pub enum MemoryOrder {
SeqCst SeqCst
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum CallConvention { pub enum CallConvention {
Mu, Mu,
Foreign(ForeignFFI) Foreign(ForeignFFI)
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum ForeignFFI { pub enum ForeignFFI {
C C
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct CallData { pub struct CallData {
pub func: OpIndex, pub func: OpIndex,
pub args: Vec<OpIndex>, pub args: Vec<OpIndex>,
...@@ -332,7 +376,7 @@ impl CallData { ...@@ -332,7 +376,7 @@ impl CallData {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ResumptionData { pub struct ResumptionData {
pub normal_dest: Destination, pub normal_dest: Destination,
pub exn_dest: Destination pub exn_dest: Destination
...@@ -344,7 +388,7 @@ impl ResumptionData { ...@@ -344,7 +388,7 @@ impl ResumptionData {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Destination { pub struct Destination {
pub target: MuID, pub target: MuID,
pub args: Vec<DestArg> pub args: Vec<DestArg>
...@@ -377,7 +421,7 @@ impl Destination { ...@@ -377,7 +421,7 @@ impl Destination {
} }
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum DestArg { pub enum DestArg {
Normal(OpIndex), Normal(OpIndex),
Freshbound(usize) Freshbound(usize)
......
...@@ -54,7 +54,7 @@ pub fn new_internal_id() -> MuID { ...@@ -54,7 +54,7 @@ pub fn new_internal_id() -> MuID {
ret ret
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MuFunction { pub struct MuFunction {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
...@@ -89,7 +89,7 @@ impl fmt::Display for MuFunction { ...@@ -89,7 +89,7 @@ impl fmt::Display for MuFunction {
} }
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MuFunctionVersion { pub struct MuFunctionVersion {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
...@@ -153,8 +153,8 @@ impl MuFunctionVersion { ...@@ -153,8 +153,8 @@ impl MuFunctionVersion {
}) })
} }
pub fn new_inst(&mut self, id: MuID, v: Instruction) -> P<TreeNode> { pub fn new_inst(&mut self, id: MuID, v: Instruction) -> Box<TreeNode> {
P(TreeNode{ Box::new(TreeNode{
hdr: MuEntityHeader::unnamed(id), hdr: MuEntityHeader::unnamed(id),
op: pick_op_code_for_inst(&v), op: pick_op_code_for_inst(&v),
v: TreeNode_::Instruction(v), v: TreeNode_::Instruction(v),
...@@ -162,7 +162,7 @@ impl MuFunctionVersion { ...@@ -162,7 +162,7 @@ impl MuFunctionVersion {
} }
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct FunctionContent { pub struct FunctionContent {
pub entry: MuID, pub entry: MuID,
pub blocks: HashMap<MuID, Block> pub blocks: HashMap<MuID, Block>
...@@ -195,7 +195,7 @@ impl FunctionContent { ...@@ -195,7 +195,7 @@ impl FunctionContent {
} }
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct FunctionContext { pub struct FunctionContext {
pub value_tags: HashMap<MuName, MuID>, pub value_tags: HashMap<MuName, MuID>,
pub values: HashMap<MuID, SSAVarEntry> pub values: HashMap<MuID, SSAVarEntry>
...@@ -234,7 +234,7 @@ impl FunctionContext { ...@@ -234,7 +234,7 @@ impl FunctionContext {
} }
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct Block { pub struct Block {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
pub content: Option<BlockContent>, pub content: Option<BlockContent>,
...@@ -247,7 +247,7 @@ impl Block { ...@@ -247,7 +247,7 @@ impl Block {
} }
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct ControlFlow { pub struct ControlFlow {
pub preds : Vec<MuID>, pub preds : Vec<MuID>,
pub succs : Vec<BlockEdge> pub succs : Vec<BlockEdge>
...@@ -286,7 +286,7 @@ impl default::Default for ControlFlow { ...@@ -286,7 +286,7 @@ impl default::Default for ControlFlow {
} }
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct BlockEdge { pub struct BlockEdge {
pub target: MuID, pub target: MuID,
pub kind: EdgeKind, pub kind: EdgeKind,
...@@ -300,15 +300,15 @@ impl fmt::Display for BlockEdge { ...@@ -300,15 +300,15 @@ impl fmt::Display for BlockEdge {
} }
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum EdgeKind { pub enum EdgeKind {
Forward, Backward Forward, Backward
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BlockContent { pub struct BlockContent {
pub args: Vec<P<Value>>, pub args: Vec<P<Value>>,
pub body: Vec<P<TreeNode>>, pub body: Vec<Box<TreeNode>>,
pub keepalives: Option<Vec<P<Value>>> pub keepalives: Option<Vec<P<Value>>>
} }
...@@ -321,7 +321,7 @@ impl BlockContent { ...@@ -321,7 +321,7 @@ impl BlockContent {
match last_inst.v { match last_inst.v {
TreeNode_::Instruction(ref inst) => { TreeNode_::Instruction(ref inst) => {
let ops = inst.ops.borrow(); let ops = inst.ops.read().unwrap();
match inst.v { match inst.v {
Instruction_::Return(_) Instruction_::Return(_)
| Instruction_::ThreadExit | Instruction_::ThreadExit
...@@ -383,7 +383,7 @@ impl BlockContent { ...@@ -383,7 +383,7 @@ impl BlockContent {
} }
} }
#[derive(Debug)] #[derive(Debug, RustcEncodable, RustcDecodable)]
/// always use with P<TreeNode> /// always use with P<TreeNode>
pub struct TreeNode { pub struct TreeNode {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
...@@ -447,14 +447,14 @@ impl fmt::Display for TreeNode { ...@@ -447,14 +447,14 @@ impl fmt::Display for TreeNode {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum TreeNode_ { pub enum TreeNode_ {
Value(P<Value>), Value(P<Value>),
Instruction(Instruction) Instruction(Instruction)
} }
/// always use with P<Value> /// always use with P<Value>
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub struct Value { pub struct Value {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
pub ty: P<MuType>, pub ty: P<MuType>,
...@@ -528,7 +528,7 @@ impl fmt::Display for Value { ...@@ -528,7 +528,7 @@ impl fmt::Display for Value {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Value_ { pub enum Value_ {
SSAVar(MuID), SSAVar(MuID),
Constant(Constant), Constant(Constant),
...@@ -536,7 +536,7 @@ pub enum Value_ { ...@@ -536,7 +536,7 @@ pub enum Value_ {
Memory(MemoryLocation) Memory(MemoryLocation)
} }
#[derive(Debug, Clone)] #[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct SSAVarEntry { pub struct SSAVarEntry {
pub id: MuID, pub id: MuID,
pub name: Option<MuName>, pub name: Option<MuName>,
...@@ -566,12 +566,12 @@ impl fmt::Display for SSAVarEntry { ...@@ -566,12 +566,12 @@ impl fmt::Display for SSAVarEntry {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Constant { pub enum Constant {
Int(u64), Int(u64),
Float(f32), Float(f32),
Double(f64), Double(f64),
IRef(Address), // IRef(Address),
FuncRef(MuID), FuncRef(MuID),
UFuncRef(MuID), UFuncRef(MuID),
Vector(Vec<Constant>), Vector(Vec<Constant>),
...@@ -583,7 +583,7 @@ impl fmt::Display for Constant { ...@@ -583,7 +583,7 @@ impl fmt::Display for Constant {
&Constant::Int(v) => write!(f, "{}", v), &Constant::Int(v) => write!(f, "{}", v),
&Constant::Float(v) => write!(f, "{}", v), &Constant::Float(v) => write!(f, "{}", v),
&Constant::Double(v) => write!(f, "{}", v), &Constant::Double(v) => write!(f, "{}", v),
&Constant::IRef(v) => write!(f, "{}", v), // &Constant::IRef(v) => write!(f, "{}", v),
&Constant::FuncRef(v) => write!(f, "{}", v), &Constant::FuncRef(v) => write!(f, "{}", v),
&Constant::UFuncRef(v) => write!(f, "{}", v), &Constant::UFuncRef(v) => write!(f, "{}", v),
&Constant::Vector(ref v) => { &Constant::Vector(ref v) => {
...@@ -600,7 +600,7 @@ impl fmt::Display for Constant { ...@@ -600,7 +600,7 @@ impl fmt::Display for Constant {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum MemoryLocation { pub enum MemoryLocation {
Address{ Address{
base: P<Value>, base: P<Value>,
......
...@@ -2,7 +2,7 @@ use ast::ptr::P; ...@@ -2,7 +2,7 @@ use ast::ptr::P;
use ast::types::*; use ast::types::*;
use ast::inst::*; use ast::inst::*;
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum OpCode { pub enum OpCode {
// SSA // SSA
RegI64, RegI64,
...@@ -112,7 +112,7 @@ pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode { ...@@ -112,7 +112,7 @@ pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
} }
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum BinOp { pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n) // Int(n) BinOp Int(n) -> Int(n)
Add, Add,
...@@ -138,7 +138,7 @@ pub enum BinOp { ...@@ -138,7 +138,7 @@ pub enum BinOp {
FRem FRem
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum CmpOp { pub enum CmpOp {
// for Int comparison // for Int comparison
EQ, EQ,
...@@ -171,7 +171,7 @@ pub enum CmpOp { ...@@ -171,7 +171,7 @@ pub enum CmpOp {
FUNO FUNO
} }
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum AtomicRMWOp { pub enum AtomicRMWOp {
XCHG, XCHG,
ADD, ADD,
......
...@@ -36,37 +36,28 @@ ...@@ -36,37 +36,28 @@
//! implementation changes (using a special thread-local heap, for example). //! implementation changes (using a special thread-local heap, for example).
//! Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated. //! Moreover, a switch to, e.g. `P<'a, T>` would be easy and mostly automated.
//use std::fmt::{self, Display, Debug}; use std::fmt::{self, Display, Debug};
//use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
//use std::ops::Deref; use std::ops::Deref;
//use std::ops::DerefMut; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::Arc; use std::sync::Arc;
pub type P<T> = Arc<T>; use ast::ir::MuEntity;
///// An owned smart pointer. pub type P<T> = Arc<T>;
//pub struct P<T> { //pub struct P<T: MuEntity> {
// ptr: Box<T> // ptr: Arc<T>
//} //}
#[allow(non_snake_case)] #[allow(non_snake_case)]
/// Construct a `P<T>` from a `T` value. /// Construct a `P<T>` from a `T` value.
pub fn P<T: 'static>(value: T) -> P<T> { pub fn P<T: MuEntity>(value: T) -> P<T> {
// P {ptr: Arc::new(value)}
Arc::new(value) Arc::new(value)
} }
//impl<T: 'static> P<T> { //impl<T: MuEntity> Deref for P<T> {
// /// Move out of the pointer.
// /// Intended for chaining transformations not covered by `map`.
// pub fn and_then<U, F>(self, f: F) -> U where
// F: FnOnce(T) -> U,
// {
// f(*self.ptr)
// }
//}
//
//impl<T> Deref for P<T> {
// type Target = T; // type Target = T;
// //
// fn deref<'a>(&'a self) -> &'a T { // fn deref<'a>(&'a self) -> &'a T {
...@@ -74,45 +65,45 @@ pub fn P<T: 'static>(value: T) -> P<T> { ...@@ -74,45 +65,45 @@ pub fn P<T: 'static>(value: T) -> P<T> {
// } // }
//} //}
// //
//impl<T> DerefMut for P<T> { //impl<T: MuEntity> Clone for P<T> {
// fn deref_mut<'a>(&'a mut self) -> &'a mut T {
// &mut *self.ptr
// }
//}
//
//impl<T: 'static + Clone> Clone for P<T> {
// fn clone(&self) -> P<T> { // fn clone(&self) -> P<T> {
// P((**self).clone()) // P {ptr: self.ptr.clone()}
// } // }
//} //}
// //
//impl<T: PartialEq> PartialEq for P<T> { //impl<T: MuEntity + PartialEq> PartialEq for P<T> {
// fn eq(&self, other: &P<T>) -> bool { // fn eq(&self, other: &P<T>) -> bool {
// **self == **other // **self == **other
// } // }
//} //}
// //
//impl<T: Eq> Eq for P<T> {} //impl<T: MuEntity + Eq> Eq for P<T> {}
// //
//impl<T: Debug> Debug for P<T> { //impl<T: MuEntity + Debug> Debug for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Debug::fmt(&**self, f) // Debug::fmt(&**self, f)
// } // }
//} //}
//impl<T: Display> Display for P<T> { //impl<T: MuEntity + Display> Display for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Display::fmt(&**self, f) // Display::fmt(&**self, f)
// } // }
//} //}
// //
//impl<T> fmt::Pointer for P<T> { //impl<T: MuEntity> fmt::Pointer for P<T> {
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// fmt::Pointer::fmt(&self.ptr, f) // fmt::Pointer::fmt(&self.ptr, f)
// } // }
//} //}
// //
//impl<T: Hash> Hash for P<T> { //impl<T: MuEntity + Hash> Hash for P<T> {
// fn hash<H: Hasher>(&self, state: &mut H) { // fn hash<H: Hasher>(&self, state: &mut H) {
// (**self).hash(state); // (**self).hash(state);
// } // }
//} //}
//impl<T: MuEntity> Encodable for P<T> {
// fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
// s.emit_usize(self.id())
// }
//}
\ No newline at end of file
...@@ -8,7 +8,7 @@ use std::sync::RwLock; ...@@ -8,7 +8,7 @@ use std::sync::RwLock;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct MuType { pub struct MuType {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
pub v: MuType_ pub v: MuType_
...@@ -23,17 +23,7 @@ impl MuType { ...@@ -23,17 +23,7 @@ impl MuType {
} }
} }
//impl Encodable for MuType { #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
// 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_ { pub enum MuType_ {
/// int <length> /// int <length>
Int (usize), Int (usize),
...@@ -117,7 +107,7 @@ lazy_static! { ...@@ -117,7 +107,7 @@ lazy_static! {
pub static ref STRUCT_TAG_MAP : RwLock<HashMap<MuName, StructType_>> = RwLock::new(HashMap::new()); pub static ref STRUCT_TAG_MAP : RwLock<HashMap<MuName, StructType_>> = RwLock::new(HashMap::new());
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct StructType_ { pub struct StructType_ {
tys: Vec<P<MuType>> tys: Vec<P<MuType>>
} }
...@@ -335,7 +325,7 @@ macro_rules! is_type ( ...@@ -335,7 +325,7 @@ macro_rules! is_type (
) )
); );
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
pub struct MuFuncSig { pub struct MuFuncSig {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
pub ret_tys : Vec<P<MuType>>, pub ret_tys : Vec<P<MuType>>,
......
...@@ -38,7 +38,7 @@ impl <'a> InstructionSelection { ...@@ -38,7 +38,7 @@ impl <'a> InstructionSelection {
// 3. we need to backup/restore all the callee-saved registers // 3. we need to backup/restore all the callee-saved registers
// if any of these assumption breaks, we will need to re-emit the code // if any of these assumption breaks, we will need to re-emit the code
#[allow(unused_variables)] #[allow(unused_variables)]
fn instruction_select(&mut self, node: &'a P<TreeNode>, cur_func: &MuFunctionVersion, vm: &VM) { fn instruction_select(&mut self, node: &'a TreeNode, cur_func: &MuFunctionVersion, vm: &VM) {
trace!("instsel on node {}", node); trace!("instsel on node {}", node);
match node.v { match node.v {
...@@ -55,7 +55,7 @@ impl <'a> InstructionSelection { ...@@ -55,7 +55,7 @@ impl <'a> InstructionSelection {
} }
}; };
let ops = inst.ops.borrow(); let ops = inst.ops.read().unwrap();
self.process_dest(&ops, fallthrough_dest, cur_func, vm); self.process_dest(&ops, fallthrough_dest, cur_func, vm);
self.process_dest(&ops, branch_dest, cur_func, vm); self.process_dest(&ops, branch_dest, cur_func, vm);
...@@ -94,7 +94,7 @@ impl <'a> InstructionSelection { ...@@ -94,7 +94,7 @@ impl <'a> InstructionSelection {
}, },
Instruction_::Branch1(ref dest) => { Instruction_::Branch1(ref dest) => {
let ops = inst.ops.borrow(); let ops = inst.ops.read().unwrap();
self.process_dest(&ops, dest, cur_func, vm); self.process_dest(&ops, dest, cur_func, vm);
...@@ -108,7 +108,7 @@ impl <'a> InstructionSelection { ...@@ -108,7 +108,7 @@ impl <'a> InstructionSelection {