Commit dc7f409b authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Implemented native dumping and loading of rust objects

parent 0454a7fa
Pipeline #624 canceled with stages
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[package]
name = "mu"
version = "0.0.1"
......@@ -28,26 +28,28 @@ aot = []
jit = []
[build-dependencies]
gcc = "0.3"
gcc = "*"
[dependencies]
ast = {path = "src/ast"}
utils = {path = "src/utils"}
gc = {path = "src/gc"}
field-offset = "0.1.1"
libloading = "0.3"
lazy_static = "0.1.15"
log = "0.3.5"
stderrlog = "0.2.2"
hprof = "0.1.3"
memmap = "0.4.0"
#rodal = {path = "rodal"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
libc="*"
field-offset = "*"
libloading = "*"
lazy_static = "*"
log = "*"
stderrlog = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
rustc-serialize = "*"
time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
petgraph = "0.4.1"
serde = "*"
serde_derive = "*"
time = "*"
maplit = "*"
docopt = "*"
petgraph = "*"
extprim = "*"
num-traits = "*"
......@@ -22,7 +22,8 @@ crate-type = ["rlib"]
[dependencies]
utils = {path = "../utils"}
lazy_static = "0.1.15"
log = "0.3.5"
simple_logger = "0.4.0"
rustc-serialize = "*"
\ No newline at end of file
lazy_static = "*"
log = "*"
simple_logger = "*"
#rodal = {path = "../../rodal"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal" }
......@@ -23,7 +23,7 @@ use utils::vec_utils;
use std::fmt;
#[derive(Debug)]
// this implements RustcEncodable, RustcDecodable, Clone and Display
// this implements Clone and Display
pub struct Instruction {
pub hdr: MuEntityHeader,
pub value : Option<Vec<P<Value>>>,
......@@ -33,43 +33,6 @@ pub struct Instruction {
impl_mu_entity!(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", 4, |s| {
try!(s.emit_struct_field("hdr", 0, |s| self.hdr.encode(s)));
try!(s.emit_struct_field("value", 1, |s| self.value.encode(s)));
let ref ops = self.ops;
try!(s.emit_struct_field("ops", 2, |s| ops.encode(s)));
try!(s.emit_struct_field("v", 3, |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", 4, |d| {
let hdr = try!(d.read_struct_field("hdr", 0, |d| Decodable::decode(d)));
let value = try!(d.read_struct_field("value", 1, |d| Decodable::decode(d)));
let ops = try!(d.read_struct_field("ops", 2, |d| Decodable::decode(d)));
let v = try!(d.read_struct_field("v", 3, |d| Decodable::decode(d)));
Ok(Instruction{
hdr: hdr,
value: value,
ops: ops,
v: v
})
})
}
}
impl Clone for Instruction {
fn clone(&self) -> Self {
Instruction {
......@@ -164,7 +127,7 @@ impl fmt::Display for Instruction {
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
#[derive(Debug, Clone)]
pub enum Instruction_ {
// non-terminal instruction
......@@ -494,7 +457,7 @@ impl Instruction_ {
}
}
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone)]
pub struct BinOpStatus {
pub flag_n: bool,
pub flag_z: bool,
......@@ -542,7 +505,7 @@ impl fmt::Debug for BinOpStatus {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum MemoryOrder {
NotAtomic,
Relaxed,
......@@ -553,18 +516,18 @@ pub enum MemoryOrder {
SeqCst
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum CallConvention {
Mu,
Foreign(ForeignFFI)
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum ForeignFFI {
C
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct CallData {
pub func: OpIndex,
pub args: Vec<OpIndex>,
......@@ -581,7 +544,7 @@ impl CallData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct ResumptionData {
pub normal_dest: Destination,
pub exn_dest: Destination
......@@ -593,7 +556,7 @@ impl ResumptionData {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub struct Destination {
pub target: MuID,
pub args: Vec<DestArg>
......@@ -636,7 +599,7 @@ impl Destination {
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Clone, Debug)]
pub enum DestArg {
Normal(OpIndex),
Freshbound(usize)
......
......@@ -21,6 +21,7 @@ use utils::vec_utils;
use utils::LinkedHashMap;
use utils::LinkedHashSet;
use std;
use std::fmt;
use std::default;
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
......@@ -77,7 +78,8 @@ pub fn new_internal_id() -> MuID {
ret
}
#[derive(Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(MuFunction{hdr, sig, cur_ver, all_vers});
#[derive(Debug)]
pub struct MuFunction {
pub hdr: MuEntityHeader,
......@@ -112,7 +114,6 @@ impl fmt::Display for MuFunction {
}
}
#[derive(RustcEncodable, RustcDecodable)]
pub struct MuFunctionVersion {
pub hdr: MuEntityHeader,
......@@ -315,7 +316,7 @@ impl MuFunctionVersion {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
#[derive(Clone)]
pub struct FunctionContent {
pub entry: MuID,
pub blocks: LinkedHashMap<MuID, Block>,
......@@ -384,7 +385,7 @@ impl FunctionContent {
}
}
#[derive(Default, Debug, RustcEncodable, RustcDecodable)]
#[derive(Default, Debug)]
pub struct FunctionContext {
pub values: LinkedHashMap<MuID, SSAVarEntry>
}
......@@ -427,7 +428,7 @@ impl FunctionContext {
}
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Clone)]
pub struct Block {
pub hdr: MuEntityHeader,
pub content: Option<BlockContent>,
......@@ -468,7 +469,7 @@ impl Block {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub struct ControlFlow {
pub preds : Vec<MuID>,
pub succs : Vec<BlockEdge>
......@@ -507,7 +508,7 @@ impl default::Default for ControlFlow {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub struct BlockEdge {
pub target: MuID,
pub kind: EdgeKind,
......@@ -521,12 +522,12 @@ impl fmt::Display for BlockEdge {
}
}
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug)]
pub enum EdgeKind {
Forward, Backward
}
#[derive(RustcEncodable, RustcDecodable, Clone)]
#[derive(Clone)]
pub struct BlockContent {
pub args: Vec<P<Value>>,
pub exn_arg: Option<P<Value>>,
......@@ -622,7 +623,7 @@ impl BlockContent {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
/// always use with P<TreeNode>
pub struct TreeNode {
pub op: OpCode,
......@@ -697,14 +698,15 @@ impl fmt::Display for TreeNode {
}
}
#[derive(Debug, RustcEncodable, RustcDecodable, Clone)]
#[derive(Debug, Clone)]
pub enum TreeNode_ {
Value(P<Value>),
Instruction(Instruction)
}
/// always use with P<Value>
#[derive(PartialEq, RustcEncodable, RustcDecodable)]
rodal_struct!(Value{hdr, ty, v});
#[derive(PartialEq)]
pub struct Value {
pub hdr: MuEntityHeader,
pub ty: P<MuType>,
......@@ -847,7 +849,8 @@ impl fmt::Display for Value {
}
}
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(Value_{(SSAVar: id), (Constant: val), (Global: ty), (Memory: location)});
#[derive(Debug, Clone, PartialEq)]
pub enum Value_ {
SSAVar(MuID),
Constant(Constant),
......@@ -870,41 +873,6 @@ pub struct SSAVarEntry {
split: Option<Vec<P<Value>>>
}
impl Encodable for SSAVarEntry {
fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
s.emit_struct("SSAVarEntry", 3, |s| {
try!(s.emit_struct_field("val", 0, |s| self.val.encode(s)));
let count = self.use_count.load(Ordering::SeqCst);
try!(s.emit_struct_field("use_count", 1, |s| s.emit_usize(count)));
try!(s.emit_struct_field("expr", 2, |s| self.expr.encode(s)));
try!(s.emit_struct_field("split", 3, |s| self.split.encode(s)));
Ok(())
})
}
}
impl Decodable for SSAVarEntry {
fn decode<D: Decoder>(d: &mut D) -> Result<SSAVarEntry, D::Error> {
d.read_struct("SSAVarEntry", 3, |d| {
let val = try!(d.read_struct_field("val", 0, |d| Decodable::decode(d)));
let count = try!(d.read_struct_field("use_count", 1, |d| d.read_usize()));
let expr = try!(d.read_struct_field("expr", 2, |d| Decodable::decode(d)));
let split = try!(d.read_struct_field("split", 3, |d| Decodable::decode(d)));
let ret = SSAVarEntry {
val: val,
use_count: ATOMIC_USIZE_INIT,
expr: expr,
split: split
};
ret.use_count.store(count, Ordering::SeqCst);
Ok(ret)
})
}
}
impl SSAVarEntry {
pub fn new(val: P<Value>) -> SSAVarEntry {
let ret = SSAVarEntry {
......@@ -965,7 +933,9 @@ impl fmt::Display for SSAVarEntry {
}
}
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(Constant{(Int: val), (IntEx: val), (Float: val), (Double: val), (FuncRef: val),
(Vector: val), NullRef, (ExternSym: val), (List: val)});
#[derive(Debug, Clone, PartialEq)]
pub enum Constant {
Int(u64),
IntEx(Vec<u64>),
......@@ -1015,10 +985,12 @@ impl fmt::Display for Constant {
}
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(MemoryLocation{{Address: scale, base, offset, index}, {Symbolic: is_global, base, label}});
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryLocation {
Address{
base: P<Value>,
base: P<Value>, // +8
offset: Option<P<Value>>,
index: Option<P<Value>>,
scale: Option<u8>
......@@ -1059,17 +1031,19 @@ impl fmt::Display for MemoryLocation {
}
#[cfg(target_arch = "aarch64")]
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
rodal_enum!(MemoryLocation{{VirtualAddress: signed, base, offset, scale}, {Address: base, offset, shift, signed}, {Symbolic: label, is_global}});
#[cfg(target_arch = "aarch64")]
#[derive(Debug, Clone, PartialEq)]
pub enum MemoryLocation {
// Represents how an adress should be computed,
// will need to be converted to a real Address before being used
VirtualAddress{
// Represents base + offset*scale
// With offset being inerpreted as signed if 'signed' is true
base: P<Value>,
offset: Option<P<Value>>,
scale: u64,
signed: bool
base: P<Value>, //+8
offset: Option<P<Value>>, //+16
signed: bool, //+1
scale: u64 //+24
},
Address{
base: P<Value>, // Must be a normal 64-bit register or SP
......@@ -1119,6 +1093,7 @@ impl fmt::Display for MemoryLocation {
}
}
rodal_struct!(MuEntityHeader{id, name});
#[repr(C)]
#[derive(Debug)] // Display, PartialEq, Clone
pub struct MuEntityHeader {
......@@ -1135,34 +1110,6 @@ impl Clone for MuEntityHeader {
}
}
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;
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: name
})
})
}
}
pub fn name_check(name: MuName) -> MuName {
let name = name.replace('.', "$");
......
......@@ -12,11 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate log;
#[macro_use]
extern crate rodal;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
extern crate rustc_serialize;
extern crate utils;
#[macro_export]
......
......@@ -17,7 +17,7 @@ use types::*;
use inst::*;
use types::MuType_::*;
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
#[allow(non_camel_case_types)]
pub enum OpCode {
// SSA
......@@ -140,7 +140,7 @@ pub fn pick_op_code_for_value(ty: &P<MuType>) -> OpCode {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
Add,
......@@ -167,7 +167,7 @@ pub enum BinOp {
FRem
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CmpOp {
// for Int comparison
EQ,
......@@ -300,7 +300,7 @@ impl CmpOp {
}
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ConvOp {
TRUNC,
ZEXT,
......@@ -316,7 +316,7 @@ pub enum ConvOp {
PTRCAST
}
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum AtomicRMWOp {
XCHG,
ADD,
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
......@@ -53,7 +39,6 @@
//use std::fmt::{self, Display, Debug};
//use std::hash::{Hash, Hasher};
//use std::ops::Deref;
//use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::sync::Arc;
......@@ -112,10 +97,4 @@ pub fn P<T>(value: T) -> P<T> {
// fn hash<H: Hasher>(&self, state: &mut H) {
// (**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
......@@ -18,8 +18,10 @@ use ir::*;
use utils::POINTER_SIZE;
use utils::vec_utils;
use std;
use rodal;
use std::fmt;
use utils::LinkedHashMap;
use std::collections::HashMap;
use std::sync::RwLock;
lazy_static! {
......@@ -90,12 +92,14 @@ pub fn init_types() {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(MuType{hdr, v});
#[derive(PartialEq, Debug)]
pub struct MuType {
pub hdr: MuEntityHeader,
pub v: MuType_
}
impl MuType {
pub fn new(id: MuID, v: MuType_) -> MuType {
MuType {
......@@ -346,7 +350,11 @@ impl MuType {
pub type StructTag = MuName;
pub type HybridTag = MuName;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_enum!(MuType_{(Int: size), Float, Double, (Ref: ty), (IRef: ty), (WeakRef: ty), (UPtr: ty),
(Struct: tag), (Array: ty, size), (Hybrid: tag), Void, ThreadRef, StackRef, Tagref64,
(Vector: ty, size), (FuncRef: ty), (UFuncPtr: ty)});
#[derive(PartialEq, Debug)]
pub enum MuType_ {
/// int <length>
Int (usize),
......@@ -427,12 +435,15 @@ impl fmt::Display for MuType_ {
lazy_static! {
/// storing a map from MuName to StructType_
pub static ref STRUCT_TAG_MAP : RwLock<LinkedHashMap<StructTag, StructType_>> = RwLock::new(LinkedHashMap::new());
pub static ref STRUCT_TAG_MAP : RwLock<HashMap<StructTag, StructType_>> =
rodal::try_load_asm_name_move("STRUCT_TAG_MAP").unwrap_or(RwLock::new(HashMap::new()));
/// storing a map from MuName to HybridType_
pub static ref HYBRID_TAG_MAP : RwLock<LinkedHashMap<HybridTag, HybridType_>> = RwLock::new(LinkedHashMap::new());
pub static ref HYBRID_TAG_MAP : RwLock<HashMap<HybridTag, HybridType_>> =
rodal::try_load_asm_name_move("HYBRID_TAG_MAP").unwrap_or(RwLock::new(HashMap::new()));
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(StructType_{tys});
#[derive(PartialEq, Debug)]
pub struct StructType_ {
tys: Vec<P<MuType>>
}
......@@ -466,7 +477,8 @@ impl StructType_ {
}
}
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(HybridType_{fix_tys, var_ty});
#[derive(PartialEq, Debug)]
pub struct HybridType_ {
fix_tys: Vec<P<MuType>>,
var_ty : P<MuType>
......@@ -649,7 +661,8 @@ macro_rules! is_type (
pub type CFuncSig = MuFuncSig;
#[derive(PartialEq, Debug, RustcEncodable, RustcDecodable)]
rodal_struct!(MuFuncSig{hdr, ret_tys, arg_tys});
#[derive(PartialEq, Debug)]
pub struct MuFuncSig {
pub hdr: MuEntityHeader,
pub ret_tys : Vec<P<MuType>>,
......
......@@ -30,11 +30,13 @@ use utils::LinkedHashMap;
use ast::ptr::P;
use ast::ir::*;
use ast::types;
use std::str;
use std::usize;
use std::ops;
use std::collections::HashSet;
use std::sync::RwLock;
struct ASMCode {
name: MuName,
......@@ -2759,7 +2761,7 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
8 => f.write_fmt(format_args!(".byte {}\n", val as u8 )).unwrap(),
16 => f.write_fmt(format_args!(".word {}\n", val as u16)).unwrap(),
32 => f.write_fmt(format_args!(".long {}\n", val as u32)).unwrap(),
64 => f.write_fmt(format_args!(".quad {}\n", val as u64)).unwrap(),
64 => f.write_fmt(format_args!(".xword {}\n", val as u64)).unwrap(),
_ => panic!("unimplemented int length: {}", len)
}
}
......@@ -2771,15 +2773,15 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
}
&Constant::Double(val) => {
let bytes: [u8; 8] = unsafe {mem::transmute(val)};
f.write(".quad ".as_bytes()).unwrap();
f.write(".xword ".as_bytes()).unwrap();
f.write(&bytes).unwrap();
f.write("\n".as_bytes()).unwrap();
}
&Constant::NullRef => {
f.write_fmt(format_args!(".quad 0\n")).unwrap()
f.write_fmt(format_args!(".xword 0\n")).unwrap()
}
&Constant::ExternSym(ref name) => {
f.write_fmt(format_args!(".quad {}\n", name)).unwrap()
f.write_fmt(format_args!(".xword {}\n", name)).unwrap()
}
&Constant::List(ref vals) => {
for val in vals {
......@@ -2797,7 +2799,6 @@ pub fn emit_context_with_reloc(vm: &VM,
fields : HashMap<Address, String>) {
use std::path;
use std::io::prelude::*;
use rustc_serialize::json;
debug!("---Emit VM Context---");
create_emit_directory(vm);
......@@ -2811,9 +2812,6 @@ pub fn emit_context_with_reloc(vm: &VM,
Ok(file) => file
};
// bss
file.write_fmt(format_args!(".bss\n")).unwrap();
// data
file.write(".data\n".as_bytes()).unwrap();
......@@ -2884,20 +2882,20 @@ pub fn emit_context_with_reloc(vm: &VM,
let load_ref = unsafe {cur_addr.load::<Address>()};
if load_ref.is_zero() {
// write 0
file.write(".quad 0\n".as_bytes()).unwrap();
file.write(".xword 0\n".as_bytes()).unwrap();
} else {
let label = match relocatable_refs.get(&load_ref) {
Some(label) => label,
None => panic!("cannot find label for address {}, it is not dumped by GC (why GC didn't trace to it)", load_ref)
};
file.write_fmt(format_args!(".quad {}\n", label.clone())).unwrap();
file.write_fmt(format_args!(".xword {}\n", label.clone())).unwrap();
}
} else if fields.contains_key(&cur_addr) {
// write uptr (or other relocatable value) with label
let label = fields.get(&cur_addr).unwrap();
file.write_fmt(format_args!(".quad {}\n", label.clone())).unwrap();
file.write_fmt(format_args!(".xword {}\n", label.clone())).unwrap();
} else {
// write plain word (as bytes)
let next_word_addr = cur_addr.plus(POINTER_SIZE);
......@@ -2916,15 +2914,21 @@ pub fn emit_context_with_reloc(vm: &VM,
// serialize vm
trace!("start serializing vm");